BCDeploy.psm1
function GetToken { param ( [string]$tenantId = "", [string]$clientId = "", [string]$clientSecret = "" ) $body = @{grant_type="client_credentials"; scope="https://api.businesscentral.dynamics.com/.default"; client_id=$clientID; client_secret=$clientSecret; client_info=1} $token = (Invoke-RestMethod -Method Post -Uri $("https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token") -Body $body).access_token return $token; } function FindApp { param( [string]$folder, [string]$app ) $file = (Get-ChildItem -Path $folder -Filter "*_${app}_*.app") $filepath = $file.FullName; $info = $file.Name.TrimEnd(".app").Split('_'); return @($info[0], $info[1], $info[2], $filepath); } function GetCompanyId { param ( [string]$token = "", [string]$instance = "" ) $baseuri = "https://api.businesscentral.dynamics.com/v2.0/${instance}/api/microsoft/automation/v2.0"; $companies = Invoke-RestMethod -Method Get -Uri "${baseuri}/companies" -Headers @{Authorization = "Bearer ${token}" } $companyId = $Companies.value[0].id return $companyId } function GetStatus { param ( [string]$token = "", [string]$instance = "", [string]$companyId = "", [string]$publisher = "", [string]$name = "", [string]$version = "" ) $baseuri = "https://api.businesscentral.dynamics.com/v2.0/${instance}/api/microsoft/automation/v2.0"; $response = Invoke-RestMethod -Method Get ` -Uri "${baseuri}/companies($companyId)/extensionDeploymentStatus" ` -Headers @{Authorization = "Bearer ${token}" } Write-Debug ($response.value |Out-String) $match = $response.value ` | Where-Object { $_.publisher -eq $publisher -and $_.name -eq $name -and $_.appVersion -eq $version } Write-Debug ($match |Out-String) if(@($match).count -gt 0) { return $match[0].status; } else { return "Unknown"; } } function GetUpload { param ( [string]$token = "", [string]$instance = "", [string]$companyId = "" ) $baseuri = "https://api.businesscentral.dynamics.com/v2.0/${instance}/api/microsoft/automation/v2.0"; $result = Invoke-RestMethod -Method Get ` -Uri "${baseuri}/companies($companyId)/extensionUpload" ` -Headers @{Authorization = "Bearer ${token}" } return $result.value[0] } function PostUpload { param ( [string]$token = "", [string]$instance = "", [string]$companyId = "" ) $baseuri = "https://api.businesscentral.dynamics.com/v2.0/${instance}/api/microsoft/automation/v2.0"; $result = Invoke-RestMethod -Method Post ` -Uri "${baseuri}/companies($companyId)/extensionUpload" ` -Headers @{Authorization = "Bearer ${token}" } ` -ContentType "application/json" ` -Body ( @{ "@odata.type"="#Microsoft.NAV.extensionUpload"; "systemId"=[guid]::NewGuid(); "schedule"="Current version"; } | ConvertTo-Json ) return $result.value } function PutUpload { param ( [string]$token = "", [string]$instance = "", [string]$companyId = "", [string]$uploadId = "", [string]$path = "" ) $baseuri = "https://api.businesscentral.dynamics.com/v2.0/${instance}/api/microsoft/automation/v2.0" Invoke-RestMethod ` -Method Put ` -Uri $("${baseuri}/companies(${companyId})/extensionUpload($uploadId)/extensionContent") ` -Headers @{Authorization='Bearer ' + $token;'If-Match'='*'} ` -ContentType "application/octet-stream" ` -InFile $path } function UploadUpload { param ( [string]$token = "", [string]$instance = "", [string]$companyId = "", [string]$uploadId = "" ) $baseuri = "https://api.businesscentral.dynamics.com/v2.0/${instance}/api/microsoft/automation/v2.0"; Invoke-RestMethod -Method Post ` -Uri "${baseuri}/companies(${companyId})/extensionUpload($uploadId)/Microsoft.NAV.upload" ` -Headers @{Authorization = "Bearer ${token}" } } function GetExtension { param ( [string]$token = "", [string]$instance = "", [string]$companyId = "", [string]$name = "", [string]$version = "" ) $baseuri = "https://api.businesscentral.dynamics.com/v2.0/${instance}/api/microsoft/automation/v2.0"; $result = Invoke-RestMethod -Method Get ` -Uri "${baseuri}/companies($companyId)/extensions" ` -Headers @{Authorization = "Bearer ${token}" } $match = $result.value ` | Where-Object { $_.displayName -eq $name -and "$($_.versionMajor).$($_.versionMinor).$($_.versionBuild).$($_.versionRevision)" -eq $version } return $match[0]; } function InstallExtension { param ( [string]$token = "", [string]$instance = "", [string]$companyId = "", [string]$packageId = "" ) $baseuri = "https://api.businesscentral.dynamics.com/v2.0/${instance}/api/microsoft/automation/v2.0"; Invoke-RestMethod -Method Post ` -Uri "${baseuri}/companies(${companyId})/extension($packageId)/Microsoft.NAV.install" ` -Headers @{Authorization = "Bearer ${token}" } } function Publish-Extension { param ( [string]$tenantId = "", [string]$clientId = "", [string]$clientSecret = "", [string]$instance = "", [string]$folder = "", [string]$app = "" ) $appinfo = FindApp -folder $folder -app $app $publisher = $appinfo[0]; $name = $appinfo[1]; $version = $appinfo[2]; $path = $appinfo[3]; "Publishing $publisher - $name - $version ($path)" $token = GetToken -tenantId $tenantId -clientId $clientId -clientSecret $clientSecret $companyId = GetCompanyId -token $token -instance $instance $upload = GetUpload -token $token -instance $instance -companyId $companyId if($upload) { "Using existing upload ($($upload.systemId))" } else { PostUpload -token $token -instance $instance -companyId $companyId $upload = GetUpload -token $token -instance $instance -companyId $companyId "Created new upload ($($upload.systemId))" } PutUpload -token $token -instance $instance -companyId $companyId -uploadId $upload.systemId -path $path "Uploaded app contents to $($upload.systemId)" UploadUpload -token $token -instance $instance -companyId $companyId -uploadId $upload.systemId "Uploaded app" do { Start-Sleep 5 $status = GetStatus -token $token -instance $instance -companyId $companyId -publisher $publisher -name $name -version $version "$tenantId $instance $publisher $name $version - $status" if($status -eq "Failed"){ throw "The extension upload failed." } if($status -eq "Unknown"){ throw "The extension upload status in unknown" } } while($status -ne "Completed") $extension = GetExtension -token $token -instance $instance -companyId $companyId -name $name -version $version if($extension.isInstalled -eq $false) { InstallExtension -token $token -instance $instance -companyId $companyId -packageId $extension.packageId "Installed extension $($extension.packageId)" } } |