Public/Install-UnifiedContacts.ps1

function Install-UnifiedContacts {
    [CmdletBinding()]
    Param(
        [Parameter (Mandatory = $true, HelpMessage = "The Url you can copy from your browser when you open the App Service. Format: https://portal.azure.com/#<domain>/resource/subscriptions/<subscriptionId>/resourceGroups/<ressourceGroupName>/providers/Microsoft.Web/sites/<appServiceName>/appServices")][string]$AppServiceAzureUrl,
        [Parameter (Mandatory = $true, HelpMessage = "user name and password of the sql user")][PSCredential]$SqlCredential
    )
    $ErrorActionPreference = "Stop"

    Import-Module Az.Resources
    try {
        $ResourceGroup = (($AppServiceAzureUrl -Split "resourceGroups/")[1] -Split "/")[0]
        $SubscriptionId = (($AppServiceAzureUrl -Split "subscriptions/")[1] -Split "/")[0]
        $AppServiceName = (($AppServiceAzureUrl -Split "sites/")[1] -Split "/")[0]

        Write-Host "ResourceGroup: $ResourceGroup`nSubscriptionId: $SubscriptionId`nAppServiceName: $AppServiceName"
        Write-Progress -Activity "Deployment Unified Contacts" -Status "Get Web App Information" -PercentComplete 5
        Clear-AzContext -Force
        $connect = Connect-AzAccount -Subscription $SubscriptionId -UseDeviceAuthentication
  
        $appService = Get-AzWebApp -ResourceGroupName  $ResourceGroup -Name $AppServiceName 
    
        Write-Progress -Activity "Deployment Unified Contacts" -Status "Create Admin Page App registration" -PercentComplete 10

        $appRegAdminPage = New-AppRegistration -AppRegistrationName ($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "AppRegistrationNameAdminPage" }).value -RedirectUri @("https://$($appService.EnabledHostNames[0])") -AvailableToOtherTenants $false
        Update-AppRegistration -App $appRegAdminPage -PermissionScopeValue "AdminPage.ReadWrite.All" -Permissions @("a154be20-db9c-4678-8ab7-66f6cc099a59", "c79f8feb-a9db-4090-85f9-90d820caa0eb", "1ca167d5-1655-44a1-8adf-1414072e1ef9") -AdminConsentDisplayName "AdminPage.ReadWrite.All" -AdminConsentDescription "Allows to access and use the UnifiedContacts Admin page" -ApplicationIdUri "api://$($appRegAdminPage.AppId)" -RequestedAccessTokenVersion 1
    
        Write-Progress -Activity "Deployment Unified Contacts" -Status "Create Teams App registration" -PercentComplete 20
    
        $appRegTeams = New-AppRegistration -appRegistrationName ($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "AppRegistrationNameTeamsApp" }).value -redirectUri @("https://$($appService.EnabledHostNames[0])") -AvailableToOtherTenants $true
        Update-AppRegistration -App $appRegTeams -PermissionScopeValue "access_as_user" -Permissions @("e1fe6dd8-ba31-4d61-89e7-88639da4683d", "242b9d9e-ed24-4d09-9a52-f43769beb9d4", "9c7a330d-35b3-4aa1-963d-cb2b9f927841", "08432d1b-5911-483c-86df-7980af5cdee0", "205e70e5-aba6-4c52-a976-6d2d46c48043", "a154be20-db9c-4678-8ab7-66f6cc099a59") -AdminConsentDisplayName "access_as_user" -AdminConsentDescription "Default access" -ApplicationIdUri "api://$($appService.EnabledHostNames[0])/$($appRegTeams.AppId)" -RequestedAccessTokenVersion 2

        Start-Sleep -Seconds 10
        #Refresh appReg Object
        $appRegTeams = Get-AzADApplication -ObjectId $appRegTeams.Id
        Set-TeamsAsAuthorizedClientApplication -App $appRegTeams
    
        Write-Progress -Activity "Deployment Unified Contacts" -Status "Create App secrets" -PercentComplete 30

        $appSecretAdminPage = New-AppSecret -ObjectId $appRegAdminPage.Id -SecretName "main"
        $appSecretTeamsApp = New-AppSecret -ObjectId $appRegTeams.Id -SecretName "main"
        Write-Progress -Activity "Deployment Unified Contacts" -Status "Set SQL Server Firewall Rule" -PercentComplete 40

        New-AzSqlServerFirewallRule -ResourceGroupName $ResourceGroup -ServerName ($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "SQLServer" }).value -AllowAllAzureIPs | Out-Null

        Write-Progress -Activity "Deployment Unified Contacts" -Status "Set Key Vault User Permissions" -PercentComplete 50

        $VaultName = ($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "KeyVaultName" }).value
        Set-AzKeyVaultAccessPolicy -VaultName $VaultName -UserPrincipalName $connect.Context.Account.Id -PermissionsToSecrets get, set, delete | Out-Null
        Write-Progress -Activity "Deployment Unified Contacts" -Status "Set Key Vault Secrets" -PercentComplete 60
     
        New-KeyVaultSecret -SecretValue $appRegAdminPage.AppId  -SecretName "AuthSettings--AdminPageClientId" -VaultName $VaultName | Out-Null
        New-KeyVaultSecret -SecretValue $connect.Context.Tenant.Id  -SecretName "AuthSettings--AdminPageTenantId" -VaultName $VaultName | Out-Null
        New-KeyVaultSecret -SecretValue $appSecretAdminPage  -SecretName "AuthSettings--AdminPageClientSecret" -VaultName $VaultName | Out-Null

        New-KeyVaultSecret -SecretValue $appRegTeams.AppId  -SecretName "AuthSettings--ClientId" -VaultName $VaultName | Out-Null
        New-KeyVaultSecret -SecretValue $connect.Context.Tenant.Id  -SecretName "AuthSettings--TenantId" -VaultName $VaultName | Out-Null
        New-KeyVaultSecret -SecretValue $appSecretTeamsApp  -SecretName "AuthSettings--ClientSecret" -VaultName $VaultName | Out-Null

        New-KeyVaultSecret -SecretValue "Server=tcp:$(($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "SQLServer" }).value).database.windows.net,1433;Initial Catalog=$(($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "SQLDatabase" }).value);Persist Security Info=False;User ID=$($SqlCredential.UserName);password='$($SqlCredential.GetNetworkCredential().Password)';MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" -SecretName "AuthSettings--DatabaseConnectionString" -VaultName $VaultName | Out-Null
        Write-Progress -Activity "Deployment Unified Contacts" -Status "Copy Binaries to storage Account" -PercentComplete 75
    
        $me = Get-AzADUser -UserPrincipalName $connect.Context.Account.Id
        $storageAccountName = ($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "StorageAccountName" }).value 
        New-AzRoleAssignment -ObjectId $me.Id -Scope "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Storage/storageAccounts/$storageAccountName/" -RoleDefinitionName "Storage Blob Data Contributor" | Out-Null
    
        Copy-Binaries -Destination $storageAccountName
        Write-Progress -Activity "Deployment Unified Contacts" -Status "Restart Web Apps" -PercentComplete 90

    ($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "WEBSITE_RUN_FROM_PACKAGE" }).value = "https://$(($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "AppSettings__BlobStorageUrl" }).value)/unified-contacts/binaries.zip"
        $settings = @{}
        foreach ($appsetting in $appService.SiteConfig.AppSettings) {
            $settings.add($appsetting.Name, $appsetting.Value)
        }
        $concentTeams = "https://login.microsoftonline.com/$($connect.Context.Tenant.Id)/adminconsent?client_id=$($appRegTeams.AppId)"
        $consentAdminPage = "https://login.microsoftonline.com/$($connect.Context.Tenant.Id)/adminconsent?client_id=$($appRegAdminPage.AppId)"
        Set-AzWebApp -ResourceGroupName $ResourceGroup -Name $AppServiceName -AppSettings $settings | Out-Null
        Start-Sleep -Seconds 10
        Write-Host "Please grant the Admin Page app registration permission via this link: $consentAdminPage" -ForegroundColor Cyan
        Write-Host "Please grant the Teams app registration permission via this link: $concentTeams" -ForegroundColor Cyan
        #Start-Process -Path $concentTeams
        #Start-Process -Path $consentAdminPage
        # az login
        #az ad app permission admin-consent --id $appRegTeams.Id
        #az ad app permission admin-consent --id $appRegAdminPage.Id
        Write-Host "Your Deployment was succesfull. Go to $AppServiceAzureUrl to restart your App Service." -ForegroundColor Green

    }
    catch {
        Write-Host "Your Deployment has failed. Please try to run Install-UnifiedContacts again." -ForegroundColor Red
        #clean up all resources
        if ($appRegAdminPage.Id) {
            Remove-AzADApplication -ObjectId $appRegAdminPage.Id 
        }
        if ($appRegTeams.Id) {
            Remove-AzADApplication -ObjectId $appRegTeams.Id
        }
        if ($VaultName) {
            Set-AzKeyVaultAccessPolicy -VaultName $VaultName -UserPrincipalName $connect.Context.Account.Id -PermissionsToSecrets get, set, delete, list, purge
            Start-Sleep -Seconds 10
            $keyVaultSecrets = Get-AzKeyVaultSecret -VaultName $VaultName
            foreach ($secret in $keyVaultSecrets) {
                Remove-AzKeyVaultSecret -VaultName $VaultName -Name $secret.Name -Force 
                Start-Sleep -Seconds 5
                Remove-AzKeyVaultSecret -VaultName $VaultName -Name $secret.Name -Force -InRemovedState
            }
        }
        if ($storageAccountName) {
            $me = Get-AzADUser -UserPrincipalName $connect.Context.Account.Id
            Remove-AzRoleAssignment -ObjectId $me.Id -Scope "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Storage/storageAccounts/$storageAccountName/" -RoleDefinitionName "Storage Blob Data Contributor"
        }
        if ($appService) {
 ($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "WEBSITE_RUN_FROM_PACKAGE" }).value = "https://unifiedcontacts.blob.core.windows.net/unified-contacts-releases/stable/1.4.0-alpha.1/ucPublish_1.4.0-alpha.1_824b8e82-0fd0-4b7e-b220-bdc90fdf4f69.zip"
            $settings = @{}
            foreach ($appsetting in $appService.SiteConfig.AppSettings) {
                $settings.add($appsetting.Name, $appsetting.Value)
            }
            Set-AzWebApp -ResourceGroupName $ResourceGroup -Name $AppServiceName -AppSettings $settings
       
            $fireWallRule = Get-AzSqlServerFirewallRule -ResourceGroupName $ResourceGroup -ServerName ($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "SQLServer" }).value -FirewallRuleName AllowAllAzureIPs
            if ($fireWallRule) { 
                Remove-AzSqlServerFirewallRule -ResourceGroupName $ResourceGroup -ServerName ($appService.SiteConfig.AppSettings | where-object { $_.Name -eq "SQLServer" }).value -FirewallRuleName $fireWallRule.FirewallRuleName | Out-Null
            }
            try {
                Remove-AzRoleAssignment -ObjectId $me.Id -Scope "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Storage/storageAccounts/$storageAccountName/" -RoleDefinitionName "Storage Blob Data Contributor"
            }
            catch {
                #fall through
            }
        }
    }
    Disconnect-AzAccount | Out-Null
}