BcSaaS/Install-BcAppFromAppSource.ps1
<#
.Synopsis Preview function for installing an AppSource App in an online tenant .Description Preview function for installing an AppSource App in an online tenant #> function Install-BcAppFromAppSource { Param ( [string] $containerName = $bcContainerHelperConfig.defaultContainerName, [string] $companyName = "", [string] $profile = "", [Parameter(Mandatory=$true)] [Hashtable] $bcAuthContext, [Parameter(Mandatory=$true)] [string] $environment, [timespan] $interactionTimeout = [timespan]::FromHours(24), [string] $culture = "en-US", [string] $timezone = "", [switch] $debugMode, [Parameter(Mandatory=$true)] [string] $appId, [string] $appName = $appId ) $bcAuthContext = Renew-BcAuthContext -bcAuthContext $bcAuthContext $bcEnvironment = Get-BcEnvironments -bcAuthContext $bcAuthContext | Where-Object { $_.Name -eq $environment -and $_.Type -eq "Sandbox" } if (!$bcEnvironment) { throw "Environment $environment doesn't exist in the current context or it is not a Sandbox environment." } Write-Host -ForegroundColor Yellow "NOTE: The implementation of Install-BcAppFromAppSource will be replaced by the Admin Center API implementation when available" $appExists = Get-BcPublishedApps -bcAuthContext $bcauthcontext -environment $environment | Where-Object { $_.id -eq $appid -and $_.state -eq "installed" } if ($appExists) { Write-Host -ForegroundColor Green "App $($appExists.Name) from $($appExists.Publisher) version $($appExists.Version) is already installed" } else { $response = Invoke-RestMethod -Method Get -Uri "https://businesscentral.dynamics.com/$($bcAuthContext.tenantID)/$environment/deployment/url" if($response.status -ne 'Ready') { throw "environment not ready, status is $($response.status)" } $useUrl = $response.data.Split('?')[0] $tenant = ($response.data.Split('?')[1]).Split('=')[1] $PsTestToolFolder = Join-Path $extensionsFolder "$containerName\PsConnectionTestTool" CreatePsTestToolFolder -containerName $containerName -PsTestToolFolder $PsTestToolFolder $serviceUrl = "$($useUrl.TrimEnd('/'))/cs?tenant=$tenant" $credential = New-Object pscredential 'user', (ConvertTo-SecureString -String $bcAuthContext.AccessToken -AsPlainText -Force) if ($companyName) { $serviceUrl += "&company=$([Uri]::EscapeDataString($companyName))" } if ($profile) { $serviceUrl += "&profile=$([Uri]::EscapeDataString($profile))" } . (Join-Path $PsTestToolFolder "PsTestFunctions.ps1") -newtonSoftDllPath (Join-Path $PsTestToolFolder "NewtonSoft.json.dll") -clientDllPath (Join-Path $PsTestToolFolder "Microsoft.Dynamics.Framework.UI.Client.dll") -clientContextScriptPath (Join-Path $PsTestToolFolder "ClientContext.ps1") $clientContext = $null try { $clientContext = New-ClientContext -serviceUrl $serviceUrl -auth 'AAD' -credential $credential -interactionTimeout $interactionTimeout -culture $culture -timezone $timezone -debugMode:$debugMode $dialog = $clientContext.OpenFormWithFilter(2503, "ID IS '$appId'") $bar = $clientContext.GetControlByName($dialog,"ActionBar") $InstallAction = $clientContext.GetActionByName($bar, 'Install') Write-Host "Installing $($appName)" $page = $clientContext.InvokeActionAndCatchForm($InstallAction) if ($page.ControlIdentifier -like "{000009c7-*") { Write-Host -NoNewline "Progress." $statusPage = $clientContext.OpenForm(2508) if (!($statusPage)) { throw "Couldn't open page 2508" } $repeater = $clientContext.GetControlByType($statusPage, [Microsoft.Dynamics.Framework.UI.Client.ClientRepeaterControl]) do { Start-Sleep -Seconds 2 Write-Host -NoNewline "." $index = 0 $clientContext.SelectFirstRow($repeater) $clientContext.Refresh($repeater) $status = "Failed" $row = $null while ($true) { if ($index -ge ($repeater.Offset + $repeater.DefaultViewport.Count)) { $clientContext.ScrollRepeater($repeater, 1) } $rowIndex = $index - $repeater.Offset $index++ if ($rowIndex -ge $repeater.DefaultViewport.Count) { break } $row = $repeater.DefaultViewport[$rowIndex] $nameControl = $clientContext.GetControlByName($row, "Name") $name = $nameControl.StringValue if ($name -like "*$appId*") { $status = $clientContext.GetControlByName($row, "Status").StringValue break } } } while ($status -eq "InProgress") if ($row) { if ($status -eq "Completed") { Write-Host -ForegroundColor Green " $status" } else { Write-Host -ForegroundColor Red " $status" $details = $clientContext.InvokeActionAndCatchForm($row) if ($details) { $summaryControl = $clientContext.GetControlByName($details, "OpDetails") if ($summaryControl) { Write-Host -ForegroundColor Red $summaryControl.StringValue } $viewDetailsControl = $clientContext.GetControlByName($details, "Details") if ($viewDetailsControl) { $clientContext.InvokeSystemAction($viewDetailsControl, "DrillDown") $detailsControl = $clientContext.GetControlByName($details, "Detailed Message box") if ($detailsControl -and $detailsControl.StringValue) { Write-Host -ForegroundColor Red "Error Details: $($detailsControl.StringValue)" } } $clientContext.CloseForm($details) } throw "Could not install $appName" } } } } catch { Write-Host $_.ScriptStackTrace if ($debugMode -and $clientContext) { Dump-ClientContext -clientcontext $clientContext } throw } finally { if ($clientContext) { Remove-ClientContext -clientContext $clientContext } } } } Export-ModuleMember -Function Install-BcAppFromAppSource |