Deployment/DeployApp.ps1
Param( [string] $serviceTier = 'BC170', [string] $RoleTailoredPath = "C:\Program Files\Microsoft Dynamics 365 Business Central\170\Service\", [string] $environment, [string] $tenantId, [string] $ClientID, [string] $ClientSecret, [ValidateSet('OnPrem','Cloud')] [string] $deploymentType = 'OnPrem' ) $Folder = Get-ChildItem -Path "$env:System_ArtifactsDirectory\*app*" -Recurse -Directory $appPath = Get-ChildItem -Path ($Folder.FullName +"\*app") -Recurse if($deploymentType -eq 'OnPrem'){ Import-Module $RoleTailoredPath"Microsoft.Dynamics.Nav.Apps.Management.psd1" Import-Module $RoleTailoredPath"Microsoft.Dynamics.Nav.Management.dll" #Import-NAVServerLicense $serviceTier -LicenseData ([Byte[]]$(Get-Content -Path $DeveloperLicensePath -Encoding Byte)) $Instance = Get-NAVServerInstance $serviceTier -Force if($Instance.State -eq 'Stopped'){ Start-NAVServerInstance -ServerInstance $serviceTier -Force } $appPath | ForEach-Object { $version = (Get-NAVAppInfo -Path $_).Version $appName = (Get-NAVAppInfo -Path $_).Name $oldappName = (Get-NAVAppInfo -ServerInstance $serviceTier -Name "$appName").Name if ($oldappName){ $oldVersion = (Get-NAVAppInfo -ServerInstance $serviceTier -Name "$appName").Version $oldVersion = $oldVersion[0].ToString() } Publish-NAVApp -ServerInstance $serviceTier -Path $_ -SkipVerification Sync-NAVTenant $serviceTier -Mode Sync -Force Sync-NAVApp -ServerInstance $serviceTier -Name $appName -Version $version -Force if (!$oldappName){ Install-NAVApp -ServerInstance $serviceTier -Name $appName -Version $version }else{ Start-NAVAppDataUpgrade -ServerInstance $serviceTier -Name $appName -Version $version Unpublish-NAVApp -ServerInstance $serviceTier -Name $appName -Version $oldVersion } } } if($deploymentType -eq 'Cloud') { $scopes = "https://api.businesscentral.dynamics.com/.default" $baseUrl = "https://api.businesscentral.dynamics.com/v2.0/$tenantId/$environment/api/microsoft/automation/v1.0" # Get access token $token = Get-MsalToken ` -ClientId $ClientID ` -TenantId $tenantId ` -Scopes $scopes ` -ClientSecret (ConvertTo-SecureString -String $ClientSecret -AsPlainText -Force) # Get companies $companies = Invoke-RestMethod ` -Method Get ` -Uri $("$baseurl/companies") ` -Headers @{Authorization='Bearer ' + $token.AccessToken} $companyId = $companies.value[0].id # Upload and install app Invoke-RestMethod ` -Method Patch ` -Uri $("$baseurl/companies($companyId)/extensionUpload(0)/content") ` -Headers @{Authorization='Bearer ' + $token.AccessToken;'If-Match'='*'} ` -ContentType "application/octet-stream" ` -InFile $appPath # Monitor publishing progress $inprogress = $true $completed = $false $errCount = 0 Import-Module $RoleTailoredPath"Microsoft.Dynamics.Nav.Management.dll" Import-Module $RoleTailoredPath"Microsoft.Dynamics.Nav.Apps.Management.psd1" $version = (Get-NAVAppInfo -Path $appPath).Version $appName = (Get-NAVAppInfo -Path $appPath).Name Write-Host "Waiting for publish $version $appName" while ($inprogress) { Start-Sleep -Seconds 10 try { $extensionDeploymentStatusResponse = Invoke-WebRequest ` -Method Get ` -Uri "$baseUrl/companies($companyId)/extensionDeploymentStatus" ` -Headers @{Authorization='Bearer ' + $token.AccessToken} $extensionDeploymentStatuses = (ConvertFrom-Json $extensionDeploymentStatusResponse.Content).value $inprogress = $false $completed = $true $extensionDeploymentStatuses | Where-Object { $_.name -eq "$appName" -and $_.appVersion -eq "$version" } | % { Write-Host "$($_.name) $($_.appVersion) $($_.operationType) $($_.status)" if ($_.status -eq "InProgress") { $inProgress = $true } if ($_.status -ne "Completed") { $completed = $false } } $errCount = 0 } catch { if ($errCount++ -gt 3) { $inprogress = $false } } } if (!$completed) { throw "Unable to publish app" } } |