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)
}