Modules/businessdev.ALbuild.Containers/Private/ConvertTo-BcEncodedCommand.ps1
|
function ConvertTo-BcEncodedCommand { <# .SYNOPSIS Builds a Base64 -EncodedCommand payload for running a script block inside a container. .DESCRIPTION Internal, pure helper. Prepends a strict error preference, an import of the Business Central management module (the 'docker exec ... powershell -NoProfile' session does not load it, so NAV cmdlets such as Publish-NAVApp would otherwise be unrecognised) and optional variable assignments (passed as JSON to survive the process boundary), then UTF-16LE/Base64 encodes the result for 'powershell -EncodedCommand'. Pure (no I/O), so it is unit-testable. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [scriptblock] $ScriptBlock, [hashtable] $Variables = @{}, # Return the assembled script text instead of the Base64 payload. The caller can then decide # whether to pass it via -EncodedCommand or - for scripts too long for the command line - via # a staged -File. [switch] $AsText ) # Make the BC management cmdlets (Publish-/Sync-/Install-/Get-NAVApp, Get-NAVServerInstance, ...) # available inside the container. They all ship in Microsoft.Dynamics.Nav.Management.dll under # the versioned Service folder; importing it directly avoids the NavAdminTool.ps1 welcome banner. # Tolerant (no throw) if the module is absent, so commands that need no NAV cmdlets still run. $importNavManagement = @' if (-not (Get-Command 'Get-NAVServerInstance' -ErrorAction SilentlyContinue)) { $navMgmt = @(Get-ChildItem 'C:\Program Files\Microsoft Dynamics NAV\*\Service\Management\Microsoft.Dynamics.Nav.Management.dll' -ErrorAction SilentlyContinue) if (-not $navMgmt) { $navMgmt = @(Get-ChildItem 'C:\Program Files\Microsoft Dynamics NAV' -Recurse -Filter 'Microsoft.Dynamics.Nav.Management.dll' -ErrorAction SilentlyContinue) } if ($navMgmt) { Import-Module $navMgmt[0].FullName -DisableNameChecking } } '@ $sb = [System.Text.StringBuilder]::new() [void]$sb.AppendLine('$ErrorActionPreference = ''Stop''') [void]$sb.AppendLine($importNavManagement) foreach ($key in $Variables.Keys) { $json = ($Variables[$key] | ConvertTo-Json -Compress -Depth 20) $escaped = $json -replace "'", "''" [void]$sb.AppendLine("`$$key = '$escaped' | ConvertFrom-Json") } [void]$sb.AppendLine($ScriptBlock.ToString()) if ($AsText) { return $sb.ToString() } $bytes = [System.Text.Encoding]::Unicode.GetBytes($sb.ToString()) return [System.Convert]::ToBase64String($bytes) } |