wvd-templates/wvd-management-ux/deploy/scripts/New-WVDMgmtSetup.ps1 (264 lines of code) (raw):

#Initializing variables $SubscriptionId = Get-AutomationVariable -Name 'subscriptionid' $ResourceGroupName = Get-AutomationVariable -Name 'ResourceGroupName' $RDBrokerURL = Get-AutomationVariable -Name 'RDBrokerURL' $ResourceURL = Get-AutomationVariable -Name 'ResourceURL' $fileURI = Get-AutomationVariable -Name 'fileURI' $AutomationAccountName = Get-AutomationVariable -Name 'accountName' $WebApp = Get-AutomationVariable -Name 'webApp' $ApiApp = Get-AutomationVariable -Name 'apiApp' $FileNames = "msft-wvd-saas-api.zip,msft-wvd-saas-web.zip,AzureModules.zip" $SplitFilenames = $FileNames.split(",") foreach($Filename in $SplitFilenames){ if($Filename -eq "AzureModules.zip"){ Invoke-WebRequest -Uri $fileURI/scripts/$Filename -OutFile "C:\$Filename" }else{ Invoke-WebRequest -Uri $fileURI/$Filename -OutFile "C:\$Filename" } } #New-Item -Path "C:\msft-wvd-saas-offering" -ItemType directory -Force -ErrorAction SilentlyContinue Expand-Archive "C:\AzureModules.zip" -DestinationPath 'C:\Modules\Global' -ErrorAction SilentlyContinue Import-Module Az.Accounts -Global Import-Module Az.Resources -Global Import-Module Az.Websites -Global Import-Module Az.Automation -Global Import-Module AzureAD -Global Set-ExecutionPolicy -ExecutionPolicy Undefined -Scope Process -Force -Confirm:$false Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine -Force -Confirm:$false Get-ExecutionPolicy -List #The name of the Automation Credential Asset this runbook will use to authenticate to Azure. $CredentialAssetName = 'ManagementUXDeploy' #Authenticate Azure #Get the credential with the above name from the Automation Asset store $AzCredentials = Get-AutomationPSCredential -Name $CredentialAssetName Connect-AzAccount -Environment 'AzureCloud' -Credential $AzCredentials Select-AzSubscription -SubscriptionId $SubscriptionId New-Item -Path "C:\msft-wvd-saas-web" -ItemType directory -Force -ErrorAction SilentlyContinue $WebAppDirectory = "C:\msft-wvd-saas-web" #Function to get PublishingProfileCredentials function Get-PublishingProfileCredentials ($resourceGroupName,$webAppName) { $resourceType = "Microsoft.Web/sites/config" $resourceName = "$webAppName/publishingcredentials" $publishingCredentials = Invoke-AzResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion 2015-08-01 -Force return $publishingCredentials } #Function to get KuduApiAuthorisationHeaderValue function Get-KuduApiAuthorisationHeaderValue ($resourceGroupName,$webAppName,$slotName = $null) { $publishingCredentials = Get-PublishingProfileCredentials $resourceGroupName $webAppName $slotName return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName,$publishingCredentials.Properties.PublishingPassword)))) } #Function to confirm files are uploaded or not in both azure app services function RunCommand ($dir,$command,$resourceGroupName,$webAppName,$slotName = $null) { $kuduApiAuthorisationToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppName $slotName $kuduApiUrl = "https://$webAppName.scm.azurewebsites.net/api/command" $Body = @{ "command" = $command; "dir" = $dir } $bodyContent = @($Body) | ConvertTo-Json #Write-output $bodyContent Invoke-RestMethod -Uri $kuduApiUrl ` -Headers @{ "Authorization" = $kuduApiAuthorisationToken; "If-Match" = "*" } ` -Method POST -ContentType "application/json" -Body $bodyContent } try { # Get Url of Web-App $GetWebApp = Get-AzWebApp -Name $WebApp -ResourceGroupName $ResourceGroupName $WebUrl = $GetWebApp.DefaultHostName #$requiredAccessName=$ResourceURL.Split("/")[3] $redirectURL = "https://" + "$WebUrl" + "/" #Get the credential with the above name from the Automation Asset store $Credentials = Get-AutomationPSCredential -Name $CredentialAssetName #Connect to AzureAD Connect-AzureAD -Credential $Credentials #Static value of wvdInfra web appname/appid $wvdinfraWebAppId = "5a0aa725-4958-4b0c-80a9-34562e23f3b7" $serviceIdinfo = Get-AzADServicePrincipal -ErrorAction SilentlyContinue | Where-Object { $_.ApplicationId -eq $wvdinfraWebAppId } $wvdInfraWebAppObjId = $serviceIdinfo.Id #generate unique ID based on subscription ID $unique_subscription_id = ($SubscriptionId).Replace('-','').substring(0,19) #generate the display name for native app in AAD $wvdSaaS_clientapp_display_name = "wvdSaaS" + $ResourceGroupName.ToLowerInvariant() + $unique_subscription_id.ToLowerInvariant() #Creating ClientApp Ad application in azure Active Directory $clientAdApp = New-AzureADApplication -DisplayName $wvdSaaS_clientapp_display_name -ReplyUrls $redirectURL -PublicClient $true -AvailableToOtherTenants $false -Verbose -ErrorAction Stop #Collecting WVD Serviceprincipal Api Permission $WVDServicePrincipal = Get-AzureADServicePrincipal -ObjectId $wvdInfraWebAppObjId #-SearchString $wvdInfraWebAppName | Where-Object {$_.DisplayName -eq $wvdInfraWebAppName} $AzureAdResouceAcessObject = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess" $AzureAdResouceAcessObject.ResourceAppId = $WVDServicePrincipal.AppId foreach ($permission in $WVDServicePrincipal.Oauth2Permissions) { $AzureAdResouceAcessObject.ResourceAccess += New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList $permission.Id,"Scope" } #Collecting AzureService Management Api permission $AzureServMgmtApi = Get-AzADServicePrincipal -ApplicationId "797f4846-ba00-4fd7-ba43-dac1f8f63013" $AzureAdServMgmtApi = Get-AzureADServicePrincipal -ObjectId $AzureServMgmtApi.Id $AzureServMgmtApiResouceAcessObject = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess" $AzureServMgmtApiResouceAcessObject.ResourceAppId = $AzureAdServMgmtApi.AppId foreach ($SerVMgmtAPipermission in $AzureAdServMgmtApi.Oauth2Permissions) { $AzureServMgmtApiResouceAcessObject.ResourceAccess += New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList $SerVMgmtAPipermission.Id,"Scope" } #Adding WVD Api Required Access and Azure Service Management Api required access Permissions to ClientAPP AD Application. Set-AzureADApplication -ObjectId $clientAdApp.ObjectId -RequiredResourceAccess $AzureAdResouceAcessObject,$AzureServMgmtApiResouceAcessObject -ErrorAction Stop } catch { Write-Output $_.Exception.Message throw $_.Exception.Message } if ($ApiApp) { try { # Get publishing profile from Api-App Write-Output "Getting the Publishing profile information from Api-App" $ApiAppXML = (Get-AzWebAppPublishingProfile -Name $ApiApp ` -ResourceGroupName $ResourceGroupName ` -OutputFile null) $ApiAppXML = [xml]$ApiAppXML # Extract connection information from publishing profile Write-Output "Gathering the username, password and publishurl from the Web-App Publishing Profile" $ApiAppUserName = $ApiAppXML.SelectNodes("//publishProfile[@publishMethod=`"MSDeploy`"]/@userName").value $ApiAppPassword = $ApiAppXML.SelectNodes("//publishProfile[@publishMethod=`"MSDeploy`"]/@userPWD").value $ApiAppURL = $ApiAppXML.SelectNodes("//publishProfile[@publishMethod=`"MSDeploy`"]/@publishUrl").value # Publish Api-App Package files recursively Write-Output "Uploading the Extracted files to Api-App" #Get-ChildItem $ApiAppExtractedPath | Compress-Archive -update -DestinationPath 'c:\msft-wvd-saas-Api.zip' -Verbose Test-Path -Path 'C:\msft-wvd-saas-Api.zip' $filePath = 'C:\msft-wvd-saas-Api.zip' $apiUrl = "https://$ApiAppURL/api/zipdeploy" $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $ApiAppUserName,$ApiAppPassword))) $userAgent = "powershell/1.0" Invoke-RestMethod -Uri $apiUrl -Headers @{ Authorization = ("Basic {0}" -f $base64AuthInfo) } -UserAgent $userAgent -Method POST -InFile $filePath -ContentType "multipart/form-data" $ApplicationId = $clientAdApp.AppId # Adding App Settings to Api-App Write-Output "Adding App settings to Api-App" $ApiAppSettings = @{ "ApplicationId" = "$ApplicationId"; "RDBrokerUrl" = "$RDBrokerURL"; "ResourceUrl" = "$ResourceURL"; "RedirectURI" = "https://" + "$WebUrl" + "/"; } Set-AzWebApp -AppSettings $ApiAppSettings -Name $ApiApp -ResourceGroupName $ResourceGroupName #Checking Extracted files are uploaded or not $returnvalue = RunCommand -dir "site\wwwroot\" -Command "ls web.config" -ResourceGroupName $resourceGroupName -webAppName $ApiApp if ($returnvalue.output) { Write-Output "Uploading of Extracted files to Api-App is Successful" Write-Output "Published files are uploaded successfully" } else { Write-Output "published files are not uploaded Error: $returnvalue.error" throw $returnvalue.error } } catch { Write-Output $_.Exception.Message throw $_.Exception.Message } } if ($WebApp -and $ApiApp) { try { ## PUBLISHING WEB-APP PACKAGE ## Write-Output "Extracting the Web-App Zip File" # Extract the Web-App ZIP file content. Expand-Archive -Path "C:\msft-wvd-saas-web.zip" -DestinationPath $WebAppDirectory -Force # Get the main.bundle.js file Path $MainbundlePath = Get-ChildItem $WebAppDirectory -Recurse | Where-Object { ($_.FullName -match "main\.(\w+).bundle.js$") } | ForEach-Object { $_.FullName } # Get Url of Api-App $GetUrl = Get-AzResource -ResourceName $ApiApp -ResourceGroupName $ResourceGroupName -ExpandProperties $GetApiUrl = $GetUrl.Properties | Select-Object defaultHostName $ApiUrl = $GetApiUrl.DefaultHostName # Change the Url in the main.bundle.js file with the ApiURL Write-Output "Updating the Url in main.bundle.js file with Api-app Url" (Get-Content $MainbundlePath).Replace("[api_url]","https://" + $ApiUrl) | Set-Content $MainbundlePath # Get publishing profile from web app Write-Output "Getting the Publishing profile information from Web-App" $WebAppXML = (Get-AzWebAppPublishingProfile -Name $WebApp ` -ResourceGroupName $ResourceGroupName ` -OutputFile null) $WebAppXML = [xml]$WebAppXML # Extract connection information from publishing profile Write-Output "Gathering the username, password and publishurl from the Web-App Publishing Profile" $WebAppUserName = $WebAppXML.SelectNodes("//publishProfile[@publishMethod=`"MSDeploy`"]/@userName").value $WebAppPassword = $WebAppXML.SelectNodes("//publishProfile[@publishMethod=`"MSDeploy`"]/@userPWD").value $WebAppURL = $WebAppXML.SelectNodes("//publishProfile[@publishMethod=`"MSDeploy`"]/@publishUrl").value Remove-Item "C:\msft-wvd-saas-web.zip" -Force # Publish Web-App Package files recursively Write-Output "Uploading the Extracted files to Web-App" Get-ChildItem $WebAppDirectory | Compress-Archive -update -DestinationPath 'c:\msft-wvd-saas-web.zip' -Verbose Test-Path -Path 'c:\msft-wvd-saas-web.zip' $filePath = 'C:\msft-wvd-saas-web.zip' $apiUrl = "https://$WebAppUrl/api/zipdeploy" $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $WebAppUserName,$WebApppassword))) $userAgent = "powershell/1.0" Invoke-RestMethod -Uri $apiUrl -Headers @{ Authorization = ("Basic {0}" -f $base64AuthInfo) } -UserAgent $userAgent -Method POST -InFile $filePath -ContentType "multipart/form-data" #Checking Extracted files are uploaded or not $returnvalue = RunCommand -dir "site\wwwroot\" -Command "ls web.config" -ResourceGroupName $resourceGroupName -webAppName $WebApp if ($returnvalue.output) { Write-Output "Uploading of Extracted files to Web-App is Successful" Write-Output "Published files are uploaded successfully" } else { Write-Output "Extracted files are not uploaded Error: $returnvalue.error" throw $returnvalue.error } } catch { Write-Output $_.Exception.Message throw $_.Exception.Message } Write-Output "Api URL : https://$ApiUrl" Write-Output "Web URL : https://$WebUrl" } New-PSDrive -Name RemoveAccount -PSProvider FileSystem -Root "C:\" | Out-Null @" Param( [Parameter(Mandatory=`$True)] [string] `$SubscriptionId, [Parameter(Mandatory=`$True)] [string] `$ResourceGroupName, [Parameter(Mandatory=`$True)] [string] `$AutomationAccountName, [Parameter(Mandatory=`$True)] [string] `$fileURI ) Invoke-WebRequest -Uri `$fileURI/scripts/AzureModules.zip -OutFile "C:\AzureModules.zip" Expand-Archive "C:\AzureModules.zip" -DestinationPath 'C:\Modules\Global' -ErrorAction SilentlyContinue Import-Module Az.profile Import-Module Az.Automation Import-Module Az.Resources #The name of the Automation Credential Asset this runbook will use to authenticate to Azure. `$CredentialAssetName = 'ManagementUXDeploy' #Get the credential with the above name from the Automation Asset store `$Credentials = Get-AutomationPSCredential -Name `$CredentialAssetName Add-AzAccount -Environment "AzureCloud" -Credential `$Credentials Select-AzSubscription -SubscriptionId `$SubscriptionId `$AutomationAccount = Get-AzAutomationAccount -ResourceGroupName `$ResourceGroupName -Name `$AutomationAccountName if(`$AutomationAccount){ #Remove-AzAutomationAccount -Name `$AutomationAccountName -ResourceGroupName `$ResourceGroupName -Force `$resourcedetails = Get-AzResource -Name `$AutomationAccountName -ResourceGroupName `$ResourceGroupName Remove-AzResource -ResourceId `$resourcedetails.ResourceId -Force }else{ exit } "@ | Out-File -FilePath RemoveAccount:\RemoveAccount.ps1 -Force $runbookName = 'removewvdsaasacctbook' #Create a Run Book New-AzAutomationRunbook -Name $runbookName -Type PowerShell -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName #Import modules to Automation Account $modules = "Az.profile,Az.compute,Az.resources" $modulenames = $modules.Split(",") foreach ($modulename in $modulenames) { Set-AzAutomationModule -Name $modulename -AutomationAccountName $AutomationAccountName -ResourceGroupName $ResourcegroupName } #Importe powershell file to Runbooks Import-AzAutomationRunbook -Path "C:\RemoveAccount.ps1" -Name $runbookName -Type PowerShell -ResourceGroupName $ResourcegroupName -AutomationAccountName $AutomationAccountName -Force #Publishing Runbook Publish-AzAutomationRunbook -Name $runbookName -ResourceGroupName $ResourcegroupName -AutomationAccountName $AutomationAccountName #Providing parameter values to powershell script file $params = @{ "ResourcegroupName" = $ResourcegroupName; "SubscriptionId" = $SubscriptionId; "AutomationAccountName" = $AutomationAccountName; "fileURI" = $fileURI } Start-AzAutomationRunbook -Name $runbookName -ResourceGroupName $ResourcegroupName -AutomationAccountName $AutomationAccountName -Parameters $params | Out-Null