Skip to content

Commit

Permalink
Issue3473 (#3505)
Browse files Browse the repository at this point in the history
Fixes #3473
+ allowing mixed sessions (PS5/PS7) by not reusing cached session
+ do not pre-initialize a container session
+ speed up invoke-script

---------

Co-authored-by: freddydk <freddydk@users.noreply.github.com>
  • Loading branch information
freddydk and freddydk committed Apr 24, 2024
1 parent 28af69c commit cb965cb
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 68 deletions.
2 changes: 1 addition & 1 deletion AppHandling/Clean-BcContainerDatabase.ps1
Expand Up @@ -96,7 +96,7 @@ try {
$copyTables += @("Entitlement", "Entitlement Set", "Membership Entitlement")
}

Invoke-ScriptInBCContainer -containerName $containerName -scriptblock { Param($platformVersion, $databaseName, $databaseServer, $databaseInstance, $copyTables, $multitenant)
Invoke-ScriptInBCContainer -containerName $containerName -useSession $false -usePwsh $false -scriptblock { Param($platformVersion, $databaseName, $databaseServer, $databaseInstance, $copyTables, $multitenant)

Write-Host "Stopping ServiceTier in order to replace database"
Set-NavServerInstance -ServerInstance $ServerInstance -stop
Expand Down
11 changes: 6 additions & 5 deletions AzureAD/New-AadAppsForBc.ps1
Expand Up @@ -82,12 +82,13 @@ try {
$accessToken = $bcAuthContext.accessToken
}
if ($accessToken) {
try {
# Connect-MgGraph changed type of accesstoken parameter from plain text to securestring along the way
Connect-MgGraph -accessToken (ConvertTo-SecureString -String $accessToken -AsPlainText -Force) | Out-Null
# Check the AccessToken since Microsoft Graph V2 requires a SecureString
$graphAccesTokenParameter = (Get-Command Connect-MgGraph).Parameters['AccessToken']
if ($graphAccesTokenParameter.ParameterType -eq [securestring]) {
Connect-MgGraph -AccessToken (ConvertTo-SecureString -String $accessToken -AsPlainText -Force) | Out-Null
}
catch [System.ArgumentException] {
Connect-MgGraph -accessToken $accessToken | Out-Null
else {
Connect-MgGraph -AccessToken $accessToken | Out-Null
}
}
else {
Expand Down
11 changes: 3 additions & 8 deletions AzureAD/Remove-AadAppsForBc.ps1
Expand Up @@ -39,13 +39,6 @@ try {
Install-Package Microsoft.Graph -Force -WarningAction Ignore | Out-Null
}

# Check the AccessToken since Microsoft Graph V2 requires a SecureString
$graphAccesTokenParameter = (Get-Command Connect-MgGraph).Parameters['AccessToken']

if ($graphAccesTokenParameter.ParameterType -eq [securestring]){
$useSecureStringForAccessToken = $true
}

# Connect to Microsoft.Graph
if (!$useCurrentMicrosoftGraphConnection) {
if ($bcAuthContext) {
Expand All @@ -57,7 +50,9 @@ try {
$accessToken = $bcAuthContext.accessToken
}
if ($accessToken) {
if ($useSecureStringForAccessToken){
# Check the AccessToken since Microsoft Graph V2 requires a SecureString
$graphAccesTokenParameter = (Get-Command Connect-MgGraph).Parameters['AccessToken']
if ($graphAccesTokenParameter.ParameterType -eq [securestring]) {
Connect-MgGraph -AccessToken (ConvertTo-SecureString -String $accessToken -AsPlainText -Force) | Out-Null
}
else {
Expand Down
66 changes: 36 additions & 30 deletions Bacpac/Export-NavContainerDatabasesAsBacpac.ps1
Expand Up @@ -17,6 +17,8 @@
Include this parameter to avoid checking entitlements. Entitlements are needed if the .bacpac file is to be used for cloud deployments.
.Parameter includeDacPac
Use this parameter to export databases as dacpac
.Parameter dacPacOnly
Use this parameter to export databases as dacpac only (skip Bacpac)
.Parameter commandTimeout
Timeout in seconds for the export command for every database. Default is 1 hour (3600).
.Parameter diagnostics
Expand All @@ -43,6 +45,7 @@ function Export-BcContainerDatabasesAsBacpac {
[string[]] $tenant = @("default"),
[int] $commandTimeout = 3600,
[switch] $includeDacPac,
[switch] $dacPacOnly,
[switch] $diagnostics,
[switch] $doNotCheckEntitlements,
[string[]] $additionalArguments = @()
Expand All @@ -64,7 +67,7 @@ try {
}
$containerBacpacFolder = Get-BcContainerPath -containerName $containerName -path $bacpacFolder -throw

Invoke-ScriptInBcContainer -containerName $containerName -ScriptBlock { Param([PSCredential]$sqlCredential, $bacpacFolder, $tenant, $commandTimeout, $includeDacPac, $diagnostics, $additionalArguments, $doNotCheckEntitlements)
Invoke-ScriptInBcContainer -containerName $containerName -ScriptBlock { Param([PSCredential]$sqlCredential, $bacpacFolder, $tenant, $commandTimeout, $includeDacPac, $dacPacOnly, $diagnostics, $additionalArguments, $doNotCheckEntitlements)

function CmdDo {
Param(
Expand Down Expand Up @@ -388,40 +391,43 @@ try {
[Parameter(Mandatory=$false)]
[int] $commandTimeout = 3600,
[switch] $includeDacPac,
[switch] $dacPacOnly,
[switch] $diagnostics,
[Parameter(Mandatory=$false)]
[string[]] $additionalArguments = @()
)

Write-Host "Exporting as BacPac..."
if (!$dacPacOnly) {
Write-Host "Exporting as BacPac..."

$arguments = @(
('/Action:Export'),
('/TargetFile:"'+$targetFile+'"'),
('/SourceDatabaseName:"'+$databaseName+'"'),
('/SourceServerName:"'+$databaseServer+'"'),
('/OverwriteFiles:True')
("/p:CommandTimeout=$commandTimeout")
)

if ($diagnostics) {
$arguments += @('/Diagnostics:True')
}

if ($sqlCredential) {
$arguments += @(
('/SourceUser:"'+$sqlCredential.UserName+'"'),
('/SourcePassword:"'+([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sqlCredential.Password)))+'"')
$arguments = @(
('/Action:Export'),
('/TargetFile:"'+$targetFile+'"'),
('/SourceDatabaseName:"'+$databaseName+'"'),
('/SourceServerName:"'+$databaseServer+'"'),
('/OverwriteFiles:True')
("/p:CommandTimeout=$commandTimeout")
)

if ($diagnostics) {
$arguments += @('/Diagnostics:True')
}

if ($sqlCredential) {
$arguments += @(
('/SourceUser:"'+$sqlCredential.UserName+'"'),
('/SourcePassword:"'+([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sqlCredential.Password)))+'"')
)
}

if ($additionalArguments) {
$arguments += $additionalArguments
}

CmdDo -command $sqlpackageExe -arguments ($arguments -join ' ')
}

if ($additionalArguments) {
$arguments += $additionalArguments
}

CmdDo -command $sqlpackageExe -arguments ($arguments -join ' ')

if ($includeDacPac) {
if ($includeDacPac -or $dacPacOnly) {
Write-Host "Extracting as DacPac..."
$arguments = @(
('/Action:Extract'),
Expand Down Expand Up @@ -481,7 +487,7 @@ try {
Remove-WindowsUsers -DatabaseServer $databaseServerInstance -DatabaseName $tempAppDatabaseName -sqlCredential $sqlCredential
Remove-ApplicationRoles -DatabaseServer $databaseServerInstance -DatabaseName $tempAppDatabaseName -sqlCredential $sqlCredential
Remove-NavDatabaseSystemTableData -DatabaseServer $databaseServerInstance -DatabaseName $tempAppDatabaseName -sqlCredential $sqlCredential
Do-Export -DatabaseServer $databaseServerInstance -DatabaseName $tempAppDatabaseName -sqlCredential $sqlCredential -targetFile $appBacpacFileName -commandTimeout $commandTimeout -includeDacPac:$includeDacPac -diagnostics:$diagnostics -additionalArguments $additionalArguments
Do-Export -DatabaseServer $databaseServerInstance -DatabaseName $tempAppDatabaseName -sqlCredential $sqlCredential -targetFile $appBacpacFileName -commandTimeout $commandTimeout -includeDacPac:$includeDacPac -dacPacOnly:$dacPacOnly -diagnostics:$diagnostics -additionalArguments $additionalArguments

$tenant | ForEach-Object {
$sourceDatabase = $_
Expand All @@ -499,7 +505,7 @@ try {
Remove-WindowsUsers -DatabaseServer $databaseServerInstance -DatabaseName $tempTenantDatabaseName -sqlCredential $sqlCredential
Remove-ApplicationRoles -DatabaseServer $databaseServerInstance -DatabaseName $tempTenantDatabaseName -sqlCredential $sqlCredential
Remove-NavTenantDatabaseUserData -DatabaseServer $databaseServerInstance -DatabaseName $tempTenantDatabaseName -sqlCredential $sqlCredential
Do-Export -DatabaseServer $databaseServerInstance -DatabaseName $tempTenantDatabaseName -sqlCredential $sqlCredential -targetFile $tenantBacpacFileName -commandTimeout $commandTimeout -includeDacPac:$includeDacPac -diagnostics:$diagnostics -additionalArguments $additionalArguments
Do-Export -DatabaseServer $databaseServerInstance -DatabaseName $tempTenantDatabaseName -sqlCredential $sqlCredential -targetFile $tenantBacpacFileName -commandTimeout $commandTimeout -includeDacPac:$includeDacPac -dacPacOnly:$dacPacOnly -diagnostics:$diagnostics -additionalArguments $additionalArguments
}
} else {
$tempDatabaseName = "temp$DatabaseName"
Expand All @@ -512,9 +518,9 @@ try {
Remove-ApplicationRoles -DatabaseServer $databaseServerInstance -DatabaseName $tempDatabaseName -sqlCredential $sqlCredential
Remove-NavDatabaseSystemTableData -DatabaseServer $databaseServerInstance -DatabaseName $tempDatabaseName -sqlCredential $sqlCredential
Remove-NavTenantDatabaseUserData -DatabaseServer $databaseServerInstance -DatabaseName $tempDatabaseName -sqlCredential $sqlCredential
Do-Export -DatabaseServer $databaseServerInstance -DatabaseName $tempDatabaseName -sqlCredential $sqlCredential -targetFile $bacpacFileName -commandTimeout $commandTimeout -includeDacPac:$includeDacPac -diagnostics:$diagnostics -additionalArguments $additionalArguments
Do-Export -DatabaseServer $databaseServerInstance -DatabaseName $tempDatabaseName -sqlCredential $sqlCredential -targetFile $bacpacFileName -commandTimeout $commandTimeout -includeDacPac:$includeDacPac -dacPacOnly:$dacPacOnly -diagnostics:$diagnostics -additionalArguments $additionalArguments
}
} -ArgumentList $sqlCredential, $containerBacpacFolder, $tenant, $commandTimeout, $includeDacPac, $diagnostics, $additionalArguments, $doNotCheckEntitlements
} -ArgumentList $sqlCredential, $containerBacpacFolder, $tenant, $commandTimeout, $includeDacPac, $dacPacOnly, $diagnostics, $additionalArguments, $doNotCheckEntitlements
}
catch {
TrackException -telemetryScope $telemetryScope -errorRecord $_
Expand Down
16 changes: 13 additions & 3 deletions ContainerHandling/Get-NavContainerSession.ps1
Expand Up @@ -29,8 +29,18 @@ function Get-BcContainerSession {
if ($sessions.ContainsKey($containerName)) {
$session = $sessions[$containerName]
try {
Invoke-Command -Session $session -ScriptBlock { $true } | Out-Null
if (!$reinit) { return $session }
$platformVersion = Invoke-Command -Session $session -ScriptBlock { [System.Version](get-item 'C:\Program Files\Microsoft Dynamics NAV\*\Service\Microsoft.Dynamics.Nav.Server.exe').Versioninfo.FileVersion }
if ($platformVersion -ge 24 -and ($usePwsh -xor $session.ConfigurationName -eq 'PowerShell.7')) {
# Cannot use existing session
Remove-PSSession -Session $session
$sessions.Remove($containerName)
$session = $null
}
else {
if (!$reinit) {
return $session
}
}
}
catch {
Remove-PSSession -Session $session
Expand All @@ -40,7 +50,7 @@ function Get-BcContainerSession {
}
if (!$session) {
[System.Version]$platformVersion = Get-BcContainerPlatformVersion -containerOrImageName $containerName
if ($platformVersion -lt [System.Version]"24.0.0.0") {
if ($platformVersion.Major -lt 24) {
$usePwsh = $false
}
$configurationName = 'Microsoft.PowerShell'
Expand Down
10 changes: 6 additions & 4 deletions ContainerHandling/Invoke-ScriptInNavContainer.ps1
Expand Up @@ -30,10 +30,12 @@ function Invoke-ScriptInBcContainer {
[bool] $usePwsh = $bccontainerHelperConfig.usePwshForBc24
)

$file = Join-Path $bcContainerHelperConfig.hostHelperFolder ([GUID]::NewGuid().Tostring()+'.ps1')
$containerFile = $containerFile = Get-BcContainerPath -containerName $containerName -path $file
if ($isInsideContainer -or "$containerFile" -eq "") {
$useSession = $true
if (!$useSession) {
$file = Join-Path $bcContainerHelperConfig.hostHelperFolder ([GUID]::NewGuid().Tostring()+'.ps1')
$containerFile = $containerFile = Get-BcContainerPath -containerName $containerName -path $file
if ($isInsideContainer -or "$containerFile" -eq "") {
$useSession = $true
}
}

if ($useSession) {
Expand Down
16 changes: 0 additions & 16 deletions ContainerHandling/Wait-NavContainerReady.ps1
Expand Up @@ -42,16 +42,6 @@ function Wait-BcContainerReady {
throw "Initialization of container $containerName failed"
}

if ($isAdministrator -and $bcContainerHelperConfig.usePsSession -and $cnt -eq ($timeout-30)) {
try {
if (!$sessions.ContainsKey($containerName)) {
$containerId = Get-BcContainerId -containerName $containerName
$session = New-PSSession -ContainerId $containerId -RunAsAdministrator
$sessions.Add($containerName, $session)
}
} catch {}
}

if ($cnt % 5 -eq 0) {
$inspect = docker inspect $containerName | ConvertFrom-Json
if ($inspect.State.Status -eq "exited") {
Expand All @@ -63,11 +53,6 @@ function Wait-BcContainerReady {

} while (!($log.Contains("Ready for connections!")))
Write-Host
if ($bcContainerHelperConfig.usePsSession) {
try {
Get-BcContainerSession -containerName $containerName -reinit -silent | Out-Null
} catch {}
}

Invoke-ScriptInBcContainer -containerName $containerName -scriptblock {
$boo = $true
Expand All @@ -76,7 +61,6 @@ function Wait-BcContainerReady {
Start-Sleep -Seconds 1
}
}

}
}
Set-Alias -Name Wait-NavContainerReady -Value Wait-BcContainerReady
Expand Down
2 changes: 1 addition & 1 deletion TenantHandling/New-NavContainerTenant.ps1
Expand Up @@ -46,7 +46,7 @@ try {
throw "You cannot add a tenant called tenant"
}

Invoke-ScriptInBcContainer -containerName $containerName -ScriptBlock { Param($containerName, $tenantId, [PSCredential]$sqlCredential, $sourceDatabase, $destinationDatabase, $alternateId, $doNotCopyDatabase, $allowAppDatabaseWrite, $applicationInsightsKey)
Invoke-ScriptInBcContainer -containerName $containerName -useSession $false -usePwsh $false -ScriptBlock { Param($containerName, $tenantId, [PSCredential]$sqlCredential, $sourceDatabase, $destinationDatabase, $alternateId, $doNotCopyDatabase, $allowAppDatabaseWrite, $applicationInsightsKey)

$customConfigFile = Join-Path (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service").FullName "CustomSettings.config"
[xml]$customConfig = [System.IO.File]::ReadAllText($customConfigFile)
Expand Down

0 comments on commit cb965cb

Please sign in to comment.