From 55e6b31d78ce7a56b8b504bf707b401d3127cec5 Mon Sep 17 00:00:00 2001 From: Freddy Kristiansen Date: Wed, 6 Mar 2024 08:11:56 +0100 Subject: [PATCH] issue 3369 and 3370 (#3389) Fixes #3369 Fixes #3370 Issue 3369 Patch images version 1.0.2.15 with an updated installer Add awareness of Windows 11 23H2 Patch images version 1.0.2.15 with an updated prompt.ps1, which loads PowerShell 7 modules when running pwsh Add new setting usePwshForBC24, which is default true to instruct Invoke-ScriptInBcContainer to use pwsh (PS7) instead of powershell (PS5) when invoking scripts in BC 24+ containers Add parameter usePwsh to Open-BcContainer and Invoke-ScriptInBcContainer, defaulted to the value of the usePwshForBC24 setting --------- Co-authored-by: freddydk --- BC.HelperFunctions.ps1 | 1 + .../Invoke-ScriptInNavContainer.ps1 | 24 ++++++++++++--- ContainerHandling/New-NavContainer.ps1 | 11 +++++-- ContainerHandling/New-NavImage.ps1 | 12 ++++++-- ContainerHandling/Open-NavContainer.ps1 | 29 ++++++++++++------- ReleaseNotes.txt | 5 ++++ 6 files changed, 63 insertions(+), 19 deletions(-) diff --git a/BC.HelperFunctions.ps1 b/BC.HelperFunctions.ps1 index 987cdae32..610339be3 100644 --- a/BC.HelperFunctions.ps1 +++ b/BC.HelperFunctions.ps1 @@ -14,6 +14,7 @@ function Get-ContainerHelperConfig { "genericImageName" = 'mcr.microsoft.com/businesscentral:{0}' "genericImageNameFilesOnly" = 'mcr.microsoft.com/businesscentral:{0}-filesonly' "usePsSession" = $true + "usePwshForBc24" = $true "tryWinRmSession" = !$isAdministrator "addTryCatchToScriptBlock" = $true "killPsSessionProcess" = $false diff --git a/ContainerHandling/Invoke-ScriptInNavContainer.ps1 b/ContainerHandling/Invoke-ScriptInNavContainer.ps1 index 84217f304..bee7bff7a 100644 --- a/ContainerHandling/Invoke-ScriptInNavContainer.ps1 +++ b/ContainerHandling/Invoke-ScriptInNavContainer.ps1 @@ -10,6 +10,10 @@ A pre-compiled PowerShell scriptblock to invoke .Parameter argumentList Arguments to transfer to the scriptblock in form of an object[] + .Parameter useSession + If true, the scriptblock will be invoked in a PowerShell session in the container. If false, the scriptblock will be invoked using docker exec + .Parameter usePwsh + If true, the scriptblock will be invoked using pwsh instead of powershell (when BC version is 24 or later) .Example Invoke-ScriptInBcContainer -containerName dev -scriptblock { $env:UserName } .Example @@ -22,12 +26,24 @@ function Invoke-ScriptInBcContainer { [ScriptBlock] $scriptblock, [Parameter(Mandatory=$false)] [Object[]] $argumentList, - [bool] $useSession = $bcContainerHelperConfig.usePsSession + [bool] $useSession = $bcContainerHelperConfig.usePsSession, + [bool] $usePwsh = $bccontainerHelperConfig.usePwshForBc24 ) $file = Join-Path $bcContainerHelperConfig.hostHelperFolder ([GUID]::NewGuid().Tostring()+'.ps1') $containerFile = "" - if (!$useSession) { + $shell = 'powershell' + if ($usePwsh) { + [System.Version]$platformVersion = Get-BcContainerPlatformVersion -containerOrImageName $containerName + if ($platformVersion -ge [System.Version]"24.0.0.0") { + $useSession = $false + $shell = 'pwsh' + } + else { + $usePwsh = $false + } + } + if (-not $usePwsh) { if ($isInsideContainer) { $useSession = $true } @@ -273,7 +289,7 @@ if ($exception) { $ErrorActionPreference = "Stop" #$file | Out-Host #Get-Content -encoding utf8 -path $file | Out-Host - docker exec $containerName powershell $containerFile | Out-Host + docker exec $containerName $shell $containerFile | Out-Host if($LASTEXITCODE -ne 0) { Remove-Item $file -Force -ErrorAction SilentlyContinue Remove-Item $hostOutputFile -Force -ErrorAction SilentlyContinue @@ -294,7 +310,7 @@ if ($exception) { '$result = Invoke-Command -ScriptBlock {' + $scriptblock.ToString() + '} -ArgumentList $argumentList' | Add-Content -Encoding $encoding -Path $file 'if ($result) { [System.Management.Automation.PSSerializer]::Serialize($result) | Set-Content -Encoding utf8 "'+$containerOutputFile+'" }' | Add-Content -Encoding $encoding -Path $file $ErrorActionPreference = "Stop" - docker exec $containerName powershell $containerFile | Out-Host + docker exec $containerName $shell $containerFile | Out-Host if($LASTEXITCODE -ne 0) { Remove-Item $file -Force -ErrorAction SilentlyContinue Remove-Item $hostOutputFile -Force -ErrorAction SilentlyContinue diff --git a/ContainerHandling/New-NavContainer.ps1 b/ContainerHandling/New-NavContainer.ps1 index 232b72273..bcd48df12 100644 --- a/ContainerHandling/New-NavContainer.ps1 +++ b/ContainerHandling/New-NavContainer.ps1 @@ -426,7 +426,10 @@ try { $isServerHost = $os.ProductType -eq 3 - if ($os.BuildNumber -eq 22621) { + if ($os.BuildNumber -eq 22631) { + $hostOs = "23H2" + } + elseif ($os.BuildNumber -eq 22621) { $hostOs = "22H2" } elseif ($os.BuildNumber -eq 22000) { @@ -1332,7 +1335,7 @@ try { Write-Host -ForegroundColor Yellow "WARNING: Using process isolation on Windows Desktop OS with generic image version prior to 1.0.2.4 or NAV/BC versions prior to 15.0, might require you to use HyperV isolation or disable Windows Defender while creating the container" } - if ($isolation -eq "process" -and !$isServerHost -and $os.BuildNumber -eq 22621 -and $useSSL) { + if ($isolation -eq "process" -and !$isServerHost -and ($os.BuildNumber -eq 22621 -or $os.BuildNumber -eq 22631) -and $useSSL) { Write-Host -ForegroundColor Red "WARNING: Using SSL when running Windows 11 with process isolation might not work due to a bug in Windows 11. Please use HyperV isolation or disable SSL." } @@ -1754,6 +1757,10 @@ if (Test-Path "c:\run\my\powershell-7.4.1-win-x64.msi") { Write-Host "Installing ') | Add-Content -Path "$myfolder\HelperFunctions.ps1" } + if ($version.Major -ge 24 -and $genericTag -eq [System.Version]"1.0.2.15") { + Download-File -source "https://raw.githubusercontent.com/microsoft/nav-docker/98c0702dbd607580880a3c9248cd76591868447d/generic/Run/Prompt.ps1" -destinationFile (Join-Path $myFolder "Prompt.ps1") + } + if ($version.Major -ge 15 -and $version.Major -le 18 -and $genericTag -ge [System.Version]"1.0.2.15") { if (!(Test-Path -Path "$myfolder\HelperFunctions.ps1")) { ('# Invoke default behavior diff --git a/ContainerHandling/New-NavImage.ps1 b/ContainerHandling/New-NavImage.ps1 index 77f1ca47f..7cfff2afa 100644 --- a/ContainerHandling/New-NavImage.ps1 +++ b/ContainerHandling/New-NavImage.ps1 @@ -138,7 +138,10 @@ try { $baseImage = $bestGenericImageName } - if ($os.BuildNumber -eq 22621) { + if ($os.BuildNumber -eq 22631) { + $hostOs = "23H2" + } + elseif ($os.BuildNumber -eq 22621) { $hostOs = "22H2" } elseif ($os.BuildNumber -eq 22000) { @@ -327,7 +330,7 @@ try { $startTime = [DateTime]::Now if ($populateBuildFolder) { - $genericTag = [Version]"1.0.2.14" + $genericTag = [Version]"1.0.2.15" } else { if ($baseImage -like 'mcr.microsoft.com/businesscentral:*') { @@ -494,6 +497,11 @@ try { $InstallDotNet = 'RUN start-process -Wait -FilePath "c:\run\DotNetCore.1.0.7_1.1.4-WindowsHosting.exe" -ArgumentList /quiet' } + if ($genericTag -eq [Version]"1.0.2.15" -and [Version]$appManifest.Version -ge [Version]"24.0.0.0") { + $myScripts += @( 'https://raw.githubusercontent.com/microsoft/nav-docker/4b8870e6c023c399d309e389bf32fde44fcb1871/generic/Run/240/navinstall.ps1' ) + Write-Host "Patching installer from generic image 1.0.2.15" + } + $myScripts | ForEach-Object { if ($_ -is [string]) { if ($_.StartsWith("https://", "OrdinalIgnoreCase") -or $_.StartsWith("http://", "OrdinalIgnoreCase")) { diff --git a/ContainerHandling/Open-NavContainer.ps1 b/ContainerHandling/Open-NavContainer.ps1 index e205ecded..e80e75368 100644 --- a/ContainerHandling/Open-NavContainer.ps1 +++ b/ContainerHandling/Open-NavContainer.ps1 @@ -6,29 +6,36 @@ The PowerShell prompt will have the PowerShell modules pre-loaded, meaning that you can use most PowerShell CmdLets. .Parameter containerName Name of the container for which you want to open a session + .Parameter usePwsh + If true, the powershell session opened will use pwsh instead of powershell (when BC version is 24 or later) .Example Open-BcContainer -containerName bcserver #> function Open-BcContainer { [CmdletBinding()] Param ( - [string] $containerName = $bcContainerHelperConfig.defaultContainerName + [string] $containerName = $bcContainerHelperConfig.defaultContainerName, + [bool] $usePwsh = $bccontainerHelperConfig.usePwshForBc24 ) Process { + $shell = 'powershell' try { $inspect = docker inspect $containerName | ConvertFrom-Json $version = [Version]$inspect.Config.Labels.version - $vs = "Business Central" - if ($version.Major -le 14) { - $vs = "NAV" - } - $psPrompt = """function prompt {'[$($containerName.ToUpperInvariant())] PS '+`$executionContext.SessionState.Path.CurrentLocation+('>'*(`$nestedPromptLevel+1))+' '}; Write-Host 'Welcome to the $vs Container PowerShell prompt'; Write-Host 'Microsoft Windows Version $($inspect.Config.Labels.osversion)'; Write-Host 'Windows PowerShell Version $($PSVersionTable.psversion.ToString())'; Write-Host; . 'c:\run\prompt.ps1' -silent""" - } - catch { - $psPrompt = """function prompt {'[$($containerName.ToUpperInvariant())] PS '+`$executionContext.SessionState.Path.CurrentLocation+('>'*(`$nestedPromptLevel+1))+' '}; . 'c:\run\prompt.ps1'""" - } - Start-Process "cmd.exe" @("/C";"docker exec -it $containerName powershell -noexit $psPrompt") + $vs = "Business Central" + if ($version.Major -le 14) { + $vs = "NAV" + } + if ($version.Major -ge 24 -and $usePwsh) { + $shell = 'pwsh' + } + $psPrompt = """function prompt {'[$($containerName.ToUpperInvariant())] PS '+`$executionContext.SessionState.Path.CurrentLocation+('>'*(`$nestedPromptLevel+1))+' '}; Write-Host 'Welcome to the $vs Container PowerShell prompt'; Write-Host 'Microsoft Windows Version $($inspect.Config.Labels.osversion)'; Write-Host ""Windows PowerShell Version `$(`$PSVersionTable.psversion.ToString())""; Write-Host; . 'c:\run\prompt.ps1' -silent""" + } + catch { + $psPrompt = """function prompt {'[$($containerName.ToUpperInvariant())] PS '+`$executionContext.SessionState.Path.CurrentLocation+('>'*(`$nestedPromptLevel+1))+' '}; . 'c:\run\prompt.ps1'""" + } + Start-Process "cmd.exe" @("/C";"docker exec -it $containerName $shell -noexit -command $psPrompt") } } Set-Alias -Name Open-NavContainer -Value Open-BcContainer diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt index 069ab903f..9af4231d8 100644 --- a/ReleaseNotes.txt +++ b/ReleaseNotes.txt @@ -9,6 +9,11 @@ Issue #3379 Adding -installCertificateOnHost to New-BcContainer didn't work when Issue #3376 Regression - Download-Artifacts stopped downloading pre-requisites Issue 3371 Unable to get companyname from Windows Users when running tests Disallow invoking Run-ALPipeline with `keepContainer` without specifying credentials to use +Issue 3369 Patch images version 1.0.2.15 with an updated installer +Add awareness of Windows 11 23H2 +Patch images version 1.0.2.15 with an updated prompt.ps1, which loads PowerShell 7 modules when running pwsh +Add new setting usePwshForBC24, which is default true to instruct Invoke-ScriptInBcContainer to use pwsh (PS7) instead of powershell (PS5) when invoking scripts in BC 24+ containers +Add parameter usePwsh to Open-BcContainer and Invoke-ScriptInBcContainer, defaulted to the value of the usePwshForBC24 setting 6.0.6 Include Microsoft_Business Foundation Test Libraries.app when importing test libraries (and tests)