functions/apphandling/Invoke-NavAppUpgrade.ps1
function Invoke-NavAppUpgrade { [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$ServerInstance, [Parameter(Mandatory)] [string]$AppPath, [string]$PlatformVersion, [switch]$Force ) if ([string]::IsNullOrWhiteSpace($PlatformVersion)) { # Determine platform version $PlatformVersion = Get-NAVServerPlatform -ServerInstance $ServerInstance if (-not $PlatformVersion) { Write-Error "Could not auto-detect platform version! Please use -PlatformVersion parameter." return $false } Write-Verbose "Auto-detect platform version: $PlatformVersion" } else { Write-Verbose "Using -PlatformVersion $PlatformVersion" } if ([string]::IsNullOrWhiteSpace($PlatformVersion)) { Write-Error "Unable to determine platform version! Please use -PlatformVersion parameter." return $false } if (-not ((Get-Command -Name Get-NAVAppInfo) -and (Get-Command -Name Get-NAVServerInstance))) { # Import management module & (Get-DynamicsNavModule -PlatformVersion $PlatformVersion -ModuleType NavAdminTool) } # kann Get-NAVServerInstance schon -KeyName ? $cmd = Get-Command Get-NAVServerConfiguration -ErrorAction SilentlyContinue $hasKeyName = $cmd.Parameters.ContainsKey('KeyName') # Multitenant? if ($hasKeyName) { [bool]$isMultitenant = ((Get-NAVServerConfiguration -ServerInstance $ServerInstance -KeyName Multitenant).ToLower() -eq 'true') } else { $config = Get-NAVServerConfiguration -ServerInstance $ServerInstance $multitenantNode = $config | Where-Object { $_.Name -eq 'key' -and $_.Attributes['name'].Value -eq 'Multitenant' } if ($multitenantNode) { [bool]$isMultitenant = ([string]($multitenantNode.Attributes['value'].Value).ToLower() -eq 'true') Write-Verbose "Multitenant: $isMultitenant" } else { Write-Warning "Multitenant setting not found! Assuming 'false'" $isMultitenant = $false } } Write-Verbose "Multitenant auto-detect: $isMultitenant" # AppInfo and handle AppId try { $AppInfo = Get-NAVAppInfo -Path $AppPath } catch { if ($_.Exception.Message -like '*contains corrupted data*') { Write-Error "App is not compatible with the server or app file is corrupted!" return $false } else { Write-Error $_ return $false } } if ($AppInfo.PSObject.Properties['AppId']) { $AppId = $AppInfo.AppId.Value.Guid Write-Verbose "Found AppId: $($AppId.ToString())" } elseif ($AppInfo.PSObject.Properties['Id']) { $AppId = $AppInfo.Id Write-Verbose "Found Id: $($AppId)" } else { Write-Error "AppInfo has no 'AppId' or 'Id'." return $false } # find published versions $publishedVersions = Get-NAVAppInfo -ServerInstance $ServerInstance -Id $AppInfo.AppId $isPublished = ($publishedVersions.Version -contains $AppInfo.Version) Write-Verbose "IsPublished: $isPublished" if ($isPublished) { Write-Verbose "Published versions: $($publishedVersions.Count)" } # find installed versions/tenants $installedOnTenants = Get-NAVAppTenant -ServerInstance $ServerInstance -Id $AppId if (-not $installedOnTenants) { if (-not $Force) { Write-Error "App is not installed! Cannot upgrade!" return $false } else { $installedOnTenantsCount = 0 } } else { $installedOnTenantsCount = $installedOnTenants.Count Write-Verbose "App is installed on tenants: $installedOnTenantsCount" } if (-not ($isMultitenant) -and ($installedOnTenantsCount -gt 1)) { Write-Warning "Mutlitenant detection failed! Found app installed on $($installedOnTenants.Count) tenants. Assuming Mutlitenant 'true'" $isMultitenant = $true } # Publish new version if (-not $isPublished) { try { Write-Verbose "Publish $($AppPath)" Publish-NAVApp -ServerInstance $ServerInstance -Path $AppPath -ErrorAction Stop } catch { if ($_.Exception.Message -like '*not been code signed*') { Write-Warning "Extension app has not been code signed!" Publish-NAVApp -ServerInstance $ServerInstance -Path $AppPath -SkipVerification -ErrorAction Stop } else { Write-Error $_ return $false } } } else { Write-Warning "App was already published!" } # Sync and upgrade tenants if ($isMultitenant) { Write-Verbose "Start upgrade in multitenant mode" [string[]]$upgradeTenants = @() if (-not $installedOnTenants -and $Force) { # This is the case when an app was installed but currently not is. # Usually we should only upgrade installed apps. This is what -Force stands for. # In this case we re-install apps with this upgrade. # So we only process tenants that have ExtensionDataVersion -ne $null $tenants = Get-NAVTenant -ServerInstance $ServerInstance foreach($tenant in $tenants) { $extensionDataVersion = (Get-NAVAppInfo -ServerInstance $ServerInstance -Tenant $tenant.Id -TenantSpecificProperties -Id $AppInfo.AppId)[0].ExtensionDataVersion if ($null -ne $extensionDataVersion) { $upgradeTenants += $tenant.Id } } } else { # Only tenants that currently have installed the app foreach($tenant in $installedOnTenants) { $upgradeTenants += $tenant.Id } } foreach($tenantId in $upgradeTenants) { Write-Verbose "Start upgrade process for tenant $tenantId" $extensionDataVersion = (Get-NAVAppInfo -ServerInstance $ServerInstance -Tenant $tenantId -TenantSpecificProperties -Id $AppInfo.AppId)[0].ExtensionDataVersion Write-Verbose "Current tenant ExtensionDataVersion: $extensionDataVersion" $isSynchronized = ($extensionDataVersion -eq $AppInfo.Version) if (-not $isSynchronized) { try { Write-Verbose "Synchronize $tenantId" Sync-NAVApp -ServerInstance $ServerInstance -Tenant $tenantId -Publisher $AppInfo.Publisher -Name $AppInfo.Name -Version $AppInfo.Version $isSynchronized = $true } catch { Write-Error "Sync failed for tenant $($tenantId): $_" } } else { Write-Information "Tenant $tenantId already synchronized." } if ($isSynchronized) { $needsUpgrade = (Get-NAVAppInfo -ServerInstance $ServerInstance -Tenant $tenantId -TenantSpecificProperties -Publisher $AppInfo.Publisher -Name $AppInfo.Name -Version $AppInfo.Version).NeedsUpgrade if ($needsUpgrade) { try { Write-Verbose "Upgrade $tenantId to $($AppInfo.Name) $($AppInfo.Version)" Start-NAVAppDataUpgrade -ServerInstance $ServerInstance -Tenant $tenantId -Publisher $AppInfo.Publisher -Name $AppInfo.Name -Version $AppInfo.Version } catch { Write-Error "Upgrade failed for tenant $($tenantId): $_" } } else { Write-Information "Tenant $tenantId already upgraded." } } } } else { Write-Verbose "Start upgrade in single-tenant mode" $isSynchronized = $false try { Write-Verbose "Synchronize" Sync-NAVApp -ServerInstance $ServerInstance -Publisher $AppInfo.Publisher -Name $AppInfo.Name -Version $AppInfo.Version $isSynchronized = $true } catch { Write-Error "Sync failed: $_" return $false } if ($isSynchronized) { try { Write-Verbose "Upgrade to $($AppInfo.Name) $($AppInfo.Version)" Start-NAVAppDataUpgrade -ServerInstance $ServerInstance -Publisher $AppInfo.Publisher -Name $AppInfo.Name -Version $AppInfo.Version } catch { Write-Error "Upgrade failed: $_" return $false } } } # Unpublish all old versions foreach ($oldApp in $publishedVersions) { # Failsave if ($oldApp.Version -eq $AppInfo.Verion) { continue } try { Write-Verbose "Unpublish $($oldApp.Publisher) $($oldApp.Name) $($oldApp.Version)" Unpublish-NAVApp -ServerInstance $ServerInstance -Publisher $oldApp.Publisher -Name $oldApp.Name -Version $oldApp.Version } catch { Write-Warning "Unpublish failed: $_" } } return $true } |