Merge pull request #136 from Azure/TestUAI1

Test UAI1 merge into 'main'
This commit is contained in:
Robert Smith 2021-11-04 15:23:44 -04:00 коммит произвёл GitHub
Родитель fbc5ff15cc 4ab91b25ce
Коммит 72cc3b45d2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 1340 добавлений и 1165 удалений

Просмотреть файл

@ -22,6 +22,9 @@
"displayName": "Resource Prefix"
}
},
"key-vault-name": {
"type": "string"
},
"_artifactsLocationSasToken": {
"type": "securestring",
"metadata": {
@ -34,7 +37,7 @@
"defaultValue": "[utcNow('u')]"
},
"managementVMOSSku": {
"type": "string",
"type": "string"
},
"CreateConfigureFileShareAndGPScriptURI": {
"type": "string"
@ -76,7 +79,7 @@
"metadata": {
"description": "The name of the keyvault that contains the secret."
},
"defaultValue": "[concat(parameters('resourcePrefix'), '-sharedsvcs-kv')]"
"defaultValue": "[concat(parameters('resourcePrefix'),uniqueString(subscription().id))]"
},
"KVsecretName": {
"type": "string",
@ -186,7 +189,7 @@
"storageAccountName": "[concat(uniquestring(resourceGroup().id, deployment().name))]",
"deployment-prefix": "[concat(parameters('resourcePrefix'), '-sharedsvcs')]",
"resourcegroup-name": "[concat(parameters('resourcePrefix'), '-sharedsvcs-rg')]",
"key-vault-name": "[concat(variables('deployment-prefix'), '-kv')]",
"key-vault-name": "[parameters('key-vault-name')]",
"key-vault-resourceID": "[resourceId('Microsoft.KeyVault/vaults', variables('key-vault-name'))]",
"CustomScriptExtensionName": "CreateProfileStoreAndFSLogixPolicy",
"ServerImageOffer": "WindowsServer",
@ -194,6 +197,7 @@
"ServerOSVersion": "[parameters('managementVMOSSku')]",
"existingDomainUsername": "[first(split(parameters('daUser_AdminUser'), '@'))]",
"managedDomaintoJoin": "[parameters('adds_domainName')]",
"windowsOSVersion": "[parameters('managementVMOSSku')]",
"resourceGroup": "[resourceGroup().name]",
"nicName": "[concat(parameters('resourcePrefix'),parameters('mgmtvmNameStatic'),string('-nic'))]",
"publicIPName": "[concat(parameters('resourcePrefix'),parameters('mgmtvmNameStatic'),string('-pip'))]",
@ -377,9 +381,9 @@
},
"storageProfile": {
"imageReference": {
"publisher": "[variables('imagePublisher')]",
"offer": "[variables('imageOffer')]",
"sku": "[variables('windowsOSVersion')]",
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "[parameters('managementVMOSSku')]",
"version": "latest"
},
"osDisk": {
@ -436,7 +440,7 @@
"fileUris": [
"[parameters('CreateConfigureFileShareAndGPScriptURI')]"
],
"commandToExecute": "[concat('powershell.exe -ExecutionPolicy Unrestricted -File CreateAADDSFileShare_ConfigureGP.ps1 -ResourceGroupName ', resourceGroup().name , ' -ScriptURI ',parameters('ScriptURI'), ' -AzureStorageFQDN ',parameters('AzureStorageFQDN'), ' -AzureEnvironmentName ',parameters('AzureEnvironmentName'), ' -vmNumberOfInstances ',parameters('avdHostPool_vmNumberOfInstances'), ' -evdvm_name_prefix ',parameters('avdHostPool_vmNamePrefix'), ' -StorageAccountName ',toLower(substring(concat(parameters('resourcePrefix'),uniqueString(subscription().id)), 0, 14)),' -Verbose')]"
"commandToExecute": "[concat('powershell.exe -ExecutionPolicy Unrestricted -File CreateAADDSFileShare_ConfigureGP.ps1 -ResourceGroupName ', resourceGroup().name , ' -ScriptURI ',parameters('ScriptURI'), ' -keyvaultname ',parameters('key-vault-name'), ' -AzureStorageFQDN ',parameters('AzureStorageFQDN'), ' -AzureEnvironmentName ',parameters('AzureEnvironmentName'), ' -vmNumberOfInstances ',parameters('avdHostPool_vmNumberOfInstances'), ' -evdvm_name_prefix ',parameters('avdHostPool_vmNamePrefix'), ' -StorageAccountName ',toLower(substring(concat(parameters('resourcePrefix'),uniqueString(subscription().id)), 0, 14)),' -Verbose')]"
}
}
},
@ -569,6 +573,9 @@
"adds_domainName": {
"value": "[parameters('adds_domainName')]"
},
"key-vault-name": {
"value": "[parameters('key-vault-name')]"
},
"ouPath": {
"value": ""
},
@ -602,6 +609,9 @@
"AzureStorageFQDN": {
"value": "[parameters('AzureStorageFQDN')]"
},
"managementVMOSSku": {
"value": "[parameters('managementVMOSSku')]"
},
"avdHostPool_vmNumberOfInstances": {
"value": "[parameters('avdHostPool_vmNumberOfInstances')]"
},

Просмотреть файл

@ -28,6 +28,9 @@
"script_executionUserResourceID": {
"type": "string"
},
"key-vault-name": {
"type": "string"
},
"ad_usernameUPN": {
"type": "string",
"metadata": {
@ -75,7 +78,6 @@
},
"variables": {
"deployment-prefix": "[concat(parameters('resourcePrefix'), '-sharedsvcs')]",
"key-vault-name": "[concat(variables('deployment-prefix'), '-kv')]",
"username": "[first(split(parameters('ad_usernameUPN'), '@'))]",
"domainadmin_secret_value": "[concat(toUpper(uniqueString(parameters('secret-unique-value1'))), uniqueString(parameters('secret-unique-value2')), toLower(uniqueString(parameters('secret-unique-value3'))), '!')]",
"domainadmin_group": "AAD DC Administrators",
@ -84,12 +86,12 @@
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(variables('key-vault-name'), '/', variables('username'))]",
"name": "[concat(parameters('key-vault-name'), '/', variables('username'))]",
"apiVersion": "2019-09-01",
"properties": {
"value": "[variables('domainadmin_secret_value')]",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', variables('key-vault-name'))]"
"[resourceId('Microsoft.KeyVault/vaults', parameters('key-vault-name'))]"
]
}
},
@ -99,7 +101,7 @@
"name": "createDAUser",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults/secrets', variables('key-vault-name'), variables('username'))]"
"[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('key-vault-name'), variables('username'))]"
],
"kind": "AzurePowerShell",
"identity": {
@ -111,7 +113,7 @@
"properties": {
"forceUpdateTag": "[parameters('utcValue')]",
"azPowerShellVersion": "5.4",
"arguments": "[concat('-displayName', ' ', variables('username'), ' ', '-userPrincipalName', ' ', parameters('ad_usernameUPN'), ' ', '-keyvault', ' ', variables('key-vault-name'), ' ','-forcePasswordChange', ' ', variables('forcePasswordChange'))]",
"arguments": "[concat('-displayName', ' ', variables('username'), ' ', '-userPrincipalName', ' ', parameters('ad_usernameUPN'), ' ', '-keyvault', ' ', parameters('key-vault-name'), ' ','-forcePasswordChange', ' ', variables('forcePasswordChange'))]",
"primaryScriptUri": "[parameters('addADUserScriptURI')]",
"timeout": "PT4H",
"cleanupPreference": "OnSuccess",
@ -152,6 +154,9 @@
"resourcePrefix": {
"value": "[parameters('resourcePrefix')]"
},
"key-vault-name": {
"value": "[parameters('key-vault-name')]"
},
"addADUserScriptURI": {
"value": "[concat(parameters('scriptURI'),'/addADuser.ps1')]"
},

Просмотреть файл

@ -20,10 +20,13 @@
"displayName": "Resource Prefix"
}
},
"key-vault-name": {
"type": "string"
},
"baseTime":{
"type":"string",
"defaultValue": "[utcNow('u')]"
},
},
"nestedTemplatesLocation": {
"type": "string",
"metadata": {
@ -506,13 +509,12 @@
},
"variables": {
"deployment-prefix": "[concat(parameters('resourcePrefix'), '-sharedsvcs')]",
"key-vault-name": "[concat(variables('deployment-prefix'), '-kv')]",
"createVMs": "[greater(parameters('avdHostPool_vmNumberOfInstances'),0)]",
"rdshManagedDisks": "[if(equals(parameters('vmImageType'), 'CustomVHD'), parameters('vmUseManagedDisks'), bool('true'))]",
"rdshPrefix": "[parameters('vmNamePrefix')]",
"avSetSKU": "[if(variables('rdshManagedDisks'), 'Aligned', 'Classic')]",
"existingDomainUsername": "[first(split(parameters('administratorAccountUsername'), '@'))]",
"key-vault-resourceID": "[resourceId('Microsoft.KeyVault/vaults', variables('key-vault-name'))]",
"key-vault-resourceID": "[resourceId('Microsoft.KeyVault/vaults', parameters('key-vault-name'))]",
"vhds": "[concat('vhds','/', variables('rdshPrefix'))]",
"subnet-id": "[resourceId(parameters('virtualNetworkResourceGroupName'),'Microsoft.Network/virtualNetworks/subnets',parameters('existingVnetName'), parameters('existingSubnetName'))]",
"resourceGroup": "[resourceGroup().name]",
@ -694,7 +696,7 @@
"administratorAccountPassword": {
"reference": {
"keyVault": {
"id": "[resourceId('Microsoft.KeyVault/vaults', variables('key-vault-name'))]"
"id": "[resourceId('Microsoft.KeyVault/vaults', parameters('key-vault-name'))]"
},
"secretName": "[variables('existingDomainUsername')]"
}
@ -771,7 +773,10 @@
"parameters": {
"resourcePrefix": {
"value": "[parameters('resourcePrefix')]"
},
},
"key-vault-name": {
"value": "[parameters('key-vault-name')]"
},
"artifactsLocation": {
"value": "https://wvdportalstorageblob.blob.core.windows.net/galleryartifacts/Configuration_7-20-2020.zip"
},

Просмотреть файл

@ -18,11 +18,14 @@
"displayName": "Resource Group and Resource identifier. String to be used as prefix to all Resource Group and Resource names."
}
},
"key-vault-name": {
"type": "string"
},
"aad_avduserGroup": {
"type": "string",
"metadata": {
"displayName": "AAD AVD Test Users Group"
},
},
"defaultValue": "AVD Users"
},
"createAVDUserScriptURI": {
@ -94,7 +97,7 @@
},
"variables": {
"deployment-prefix": "[concat(parameters('resourcePrefix'), '-sharedsvcs')]",
"key-vault-name": "[concat(variables('deployment-prefix'), '-kv')]",
"key-vault-name": "[parameters('key-vault-name')]",
"hostpoolName": "[replace(parameters('hostpoolName'),'\"','')]",
"pw_secret_value": "[concat(toUpper(uniqueString(parameters('secret-unique-value1'))), uniqueString(parameters('secret-unique-value2')), toLower(uniqueString(parameters('secret-unique-value3'))), '!')]",
"forcePasswordChange": true,
@ -155,6 +158,9 @@
"resourcePrefix": {
"value": "[parameters('resourcePrefix')]"
},
"key-vault-name": {
"value": "[parameters('key-vault-name')]"
},
"domainName": {
"value": "[parameters('adds_domainName')]"
},

Просмотреть файл

@ -18,6 +18,9 @@
"displayName": "Resource Group and Resource identifier. String to be used as prefix to all Resource Group and Resource names."
}
},
"key-vault-name": {
"type": "string"
},
"keyvault_ownerUserObjectID": {
"type": "string",
"metadata": {
@ -85,7 +88,7 @@
},
"variables": {
"deployment-prefix": "[concat(parameters('resourcePrefix'), '-sharedsvcs')]",
"key-vault-name": "[concat(variables('deployment-prefix'), '-kv')]",
"key-vault-name": "[parameters('key-vault-name')]",
"enable-vault-for-deployment": true,
"enable-vault-for-templateDeployment": true,
"enable-vault-for-diskEncryption": true,
@ -229,6 +232,9 @@
"resourcePrefix": {
"value": "[parameters('resourcePrefix')]"
},
"key-vault-name": {
"value": "[parameters('key-vault-name')]"
},
"keyvault_ownerUserObjectID": {
"value": "[parameters('keyvault_ownerUserObjectID')]"
},

Просмотреть файл

@ -82,6 +82,10 @@
"defaultValue": "[concat(parameters('resourcePrefix'), '-sharedsvcs-vnet')]",
"allowedValues": []
},
"key-vault-name": {
"type": "string",
"defaultValue": "[concat(parameters('resourcePrefix'),uniqueString(subscription().id))]"
},
"script_executionUserResourceID": {
"type": "string",
"metadata": {
@ -142,7 +146,7 @@
"displayName": "Management VM OS Sku",
"description": "The Windows Sku of the VM used to manage AAD DS"
},
"defaultValue": "2022-datacenter",
"defaultValue": "2022-datacenter"
},
"avdHostPool_CreateAvailabilitySet": {
"type": "bool",
@ -213,7 +217,7 @@
2,
3
]
},
},
"log-analytics_service-tier": {
"type": "string",
"metadata": {
@ -333,27 +337,9 @@
},
"avdHostPool_vmGalleryImageSKU": {
"type": "string",
"allowedValues": [
"19h2-evd-o365pp",
"19h2-evd-o365pp-g2",
"20h1-evd-o365pp",
"20h1-evd-o365pp-g2",
"20h2-evd-o365pp",
"20h2-evd-o365pp-g2",
"21h1-evd-o365pp",
"21h1-evd-o365pp-g2",
"19h2-evd",
"19h2-evd-g2",
"20h1-evd",
"20h1-evd-g2",
"20h2-evd",
"20h2-evd-g2",
"21h1-evd",
"21h1-evd-g2"
],
"metadata": {
"displayName": "Azure Gallery image SKU",
"description": "20h1=2004, 20h2=2009, 21h1=21h1"
"displayName": "AVD session host Gallery OS image SKU",
"description": "The Windows version that will be used to create the AVD session hosts"
},
"defaultValue": "21h1-evd-o365pp"
},

Просмотреть файл

@ -2,15 +2,15 @@
"AzureSubscriptionID": "",
"AzureTenantID": "",
"AADDSDomainName": "",
"BlueprintResourcePrefix": "Please delete this text and enter a 6-8 character random string of text",
"BlueprintResourcePrefix": "",
"PromptForSessionHostOSSku": true,
"PromptForManagementVMOSSku": false,
"avdHostPool_vmGalleryImageSKU": "21h1-evd-o365pp",
"avdHostPool_vmSize": "Standard_B4ms",
"avdHostPool_vmNumberOfInstances": 2,
"avdHostPool_maxSessionLimit": 16,
"avdUsers_userCount": 30,
"BlueprintGlobalResourceGroupName": "AVD_Blueprint_Global_RG",
"UserAssignedIdentityName": "UAI1",
"BlueprintName": "AVDBlueprint",

Просмотреть файл

@ -53,7 +53,7 @@ $BPScriptParams
- TITLE: AVD Blueprint Configuration and Deployment script
- AUTHORED BY: Robert M. Smith
- AUTHORED DATE: 01 September 2021
- CONTRIBUTORS: Tim Muessig, Jason Masten, Dennis Payne
- CONTRIBUTORS: Tim Muessig, Jason Masten, Dennis Payne, Chris Rutledge
- LAST UPDATED: 30 September 2021
- PURPOSE: A single PowerShell script to perform everything necessary to deploy Azure Virtual Desktop (AVD)
into an Azure Subscription
@ -113,29 +113,39 @@ $BPScriptParams
######################################################################################################################################>
#region Checking for the required parameters, and if not set, exit script
Write-Host "Checking PowerShell installed modules..." -ForegroundColor Cyan
#region Checking for the first two required parameters, and if not set, exit script
if (-not($AADDSDomainName)) {
Write-Host "`n Azure Active Directory Domain Services name is null
Write-Host "`n Azure Active Directory Domain Services name is not found
AAD DS name must be specified in the parameter file 'AVDBPParameters.json'
Your AAD DS prefix name must be 15 characters or less in the format 'domain.contoso.com'
This script will now exit." -ForegroundColor Cyan
This script will now exit." -ForegroundColor Red
Return
}
if (-not($AzureTenantID)) {
Write-Host "`n Azure Tenant ID is missing.
The destination Azure Tenant ID must be present in the file'AVDBPParameters.json'.
This script will now exit." -ForegroundColor Cyan
This script will now exit." -ForegroundColor Red
Return
}
if (-not($AzureSubscriptionID)) {
Write-Host "`n Azure Subscription ID is missing.
The destination Azure Subscription ID must be present in the file'AVDBPParameters.json'.
This script will now exit." -ForegroundColor Cyan
This script will now exit." -ForegroundColor Red
Return
}
if (-not($BlueprintResourcePrefix)) {
Write-Host "`n 'BlueprintResourcePrefix' parameter value is missing in the parameter file 'AVDBPParameters.json'
Please enter a 4-8 character value to be used for the blueprint deployment prefix.
This prefix is used in naming some objects during the blueprint deployment, including computer names.
Prefixes longer than 8 or 9 characters start to limit number of session hosts VMs that can get created because of name length.
This script will now exit." -ForegroundColor Red
Return
}
#endregion
#region Make sure required Az modules are installed
@ -148,6 +158,8 @@ if (-not($AzureSubscriptionID)) {
# - Az.Resources
# - AzureAD
Write-Host "Checking PowerShell installed modules..." -ForegroundColor Cyan
$AzModuleGalleryMessage = "You may be prompted to install from the PowerShell Gallery`n
If the Az PowerShell modules were not previously installed you may be prompted to install 'Nuget'.`n
If your policies allow those items to be installed, click 'Yes to All' when prompted."
@ -268,14 +280,6 @@ $AzureEnvironment = Get-AzContext
$AzureStorageEnvironment = ($AzureEnvironment).Environment.StorageEndpointSuffix
$AzureStorageFileEnv = 'file.' + $AzureStorageEnvironment
# Set the correct value for 'avdHostPool_vmGalleryImageOffer' based on the VM type being installed'
if ($avdHostPool_vmGalleryImageSKU -like '*o365pp*')
{
$avdHostPool_vmGalleryImageOffer = "office-365"
} else {
$avdHostPool_vmGalleryImageOffer = "windows-10"
}
Write-Host "`n Enumerating list of locations in your environment, that offer the AVD service..." -ForegroundColor Cyan
$AzureLocations = (Get-AzResourceProvider -ListAvailable | Where-Object {($_.ProviderNamespace -EQ "Microsoft.DesktopVirtualization" -and $_.RegistrationState -EQ "Registered")}).Locations.ToLower() -replace '\s',''
@ -345,7 +349,7 @@ if ($result -eq [System.Windows.Forms.DialogResult]::OK)
#region If management VM Sku prompt set true, query and display available Skus
if ($PromptForManagementVMOSSku){
Write-Host "`n Gathering list of available Server Windows Skus..." -ForegroundColor Cyan
$ServerSkus = Get-AzVMImageSku -Location $ChosenAzureLocation -PublisherName 'MicrosoftWindowsServer' -Offer 'WindowsServer' | Where-Object {$_.Skus -like "20??-datacenter*"}| foreach { $_.Skus}
$ServerSkus = Get-AzVMImageSku -Location $ChosenAzureLocation -PublisherName 'MicrosoftWindowsServer' -Offer 'WindowsServer' | Where-Object {$_.Skus -like "20??-datacenter*" -and $_.Skus -notlike "*core*" -and $_.Skus -notlike "*smalldisk*" -and $_.Skus -notlike "*containers*"} | Select-object -Expandproperty Skus
# Present a pop-up form to select management VM OS Sku to build from
Add-Type -AssemblyName System.Windows.Forms
@ -415,12 +419,97 @@ $managementVMOSSku = '2022-datacenter'
}
#endregion
#region If AVD session host prompt set true, query and display available Skus
if ($PromptForSessionHostOSSku){
Write-Host "`n Gathering list of available Windows session host SKUs..." -ForegroundColor Cyan
$AVDSHvmsku = Get-AzVMImageSku -Location $ChosenAzureLocation -PublisherName 'MicrosoftWindowsDesktop' -offer 'windows-10' | Where-Object ({$_.Skus -like "*evd*" -and $_.Skus -notlike "*rs5*" -or $_.Skus -like "*avd*"})| Select-Object -ExpandProperty Skus
$AVDSHvmsku += Get-AzVMImageSku -Location $ChosenAzureLocation -PublisherName 'MicrosoftWindowsDesktop' -offer 'office-365' | Where-Object ({$_.Skus -like "*evd*" -and $_.Skus -notlike "*rs5*" -or $_.Skus -like "*avd*"})| Select-Object -ExpandProperty Skus
$AVDSHvmsku += Get-AzVMImageSku -Location $ChosenAzureLocation -PublisherName 'MicrosoftWindowsDesktop' -offer 'windows-11' | Where-Object ({$_.Skus -like "*evd*" -and $_.Skus -notlike "*rs5*" -or $_.Skus -like "*avd*"})| Select-Object -ExpandProperty Skus
# Present a pop-up form to select management VM OS Sku to build from
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = 'AVD OS Sku'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(75,120)
$okButton.Size = New-Object System.Drawing.Size(75,23)
$okButton.Text = 'OK'
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $okButton
$form.Controls.Add($okButton)
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(150,120)
$cancelButton.Size = New-Object System.Drawing.Size(75,23)
$cancelButton.Text = 'Cancel'
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $cancelButton
$form.Controls.Add($cancelButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Please select AVD OS Sku:'
$form.Controls.Add($label)
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80
ForEach ($A in $AVDSHvmsku){
Write-Output $A | ForEach-Object {[void] $listBox.Items.Add($_)}
}
$form.Controls.Add($listBox)
$form.Topmost = $true
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::CANCEL)
{
Write-Host "The 'Cancel' button was pressed. The script will now exit." -ForegroundColor Red
Return
}
if ($null -eq $listBox.SelectedItem)
{
Write-Host " A Windows Server OS Sku was not selected.
Please re-run this script and select a Windows OS Sku in the pop-up pick-list" -ForegroundColor Red
Return
}
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$avdHostPool_vmGalleryImageSKU = $listBox.SelectedItem
# Set the correct 'ImageOffer' based on the image selected
if (Get-AzVMImage -Location $ChosenAzureLocation -PublisherName 'MicrosoftWindowsDesktop' -Offer 'windows-10' -Sku $avdHostPool_vmGalleryImageSKU -ErrorAction SilentlyContinue) {
$avdHostPool_vmGalleryImageOffer = 'windows-10'
} elseif (Get-AzVMImage -Location $ChosenAzureLocation -PublisherName 'MicrosoftWindowsDesktop' -Offer 'windows-11' -Sku $avdHostPool_vmGalleryImageSKU -ErrorAction SilentlyContinue) {
$avdHostPool_vmGalleryImageOffer = 'windows-11'
} elseif (Get-AzVMImage -Location $ChosenAzureLocation -PublisherName 'MicrosoftWindowsDesktop' -Offer 'office-365' -Sku $avdHostPool_vmGalleryImageSKU -ErrorAction SilentlyContinue) {
$avdHostPool_vmGalleryImageOffer = 'office-365'
}
Write-Host "Your chosen Windows session host OS Sku is '$avdHostPool_vmGalleryImageSKU'"
}
} else {
$avdHostPool_vmGalleryImageSKU = '21h1-evd-o365pp'
}
#endregion
Write-Host "`nThe following parameters will be used, based on the login information provided:
Azure Tenant ID: $AzureTenantID
Azure Subscription ID: $AzureSubscriptionID
Azure Cloud Instance: $AzureEnvironmentName
Azure Location: $ChosenAzureLocation`n" -ForegroundColor Cyan
Azure Location: $ChosenAzureLocation
`n" -ForegroundColor Cyan
$UserPrincipalName = (Get-AzContext).Account.Id
#Internal Account
@ -459,13 +548,20 @@ Connect-AzureAD -AzureEnvironmentName $AzureEnvironmentName -TenantId $AzureTena
$ManagedIdentityCheck = Get-AzUserAssignedIdentity -Name $UserAssignedIdentityName -ResourceGroupName $BlueprintGlobalResourceGroupName -ErrorAction SilentlyContinue
Write-Host "`nCreating user-assigned managed identity account, that will be the context of the AVD assignment" -ForegroundColor Cyan
If (-not($ManagedIdentityCheck)){
$UserAssignedIdentity = Get-AzUserAssignedIdentity -Name $UserAssignedIdentityName -ResourceGroupName $BlueprintGlobalResourceGroupName -ErrorAction SilentlyContinue
Write-Host "`nCreating user-assigned managed identity account, which will be the context of the AVD assignment" -ForegroundColor Cyan
}
If (-not($UserAssignedIdentity)){
Write-Host " Managed identity '$UserAssignedIdentityName' does not currently exist.
Now creating managed identity '$UserAssignedIdentityName' in resource group '$BlueprintGlobalResourceGroupName'" -ForegroundColor Cyan
$UserAssignedIdentity = New-AzUserAssignedIdentity -ResourceGroupName $BlueprintGlobalResourceGroupName -Name $UserAssignedIdentityName -Location $ChosenAzureLocation
$UserAssignedIdentity
} else {
Write-Host "`nUser Assigned Identity '$UserAssignedIdentityName' already exists`n" -ForegroundColor Cyan
$UserAssignedIdentity = $ManagedIdentityCheck
$ManagedIdentityCheck
$UserAssignedIdentity = Get-AzUserAssignedIdentity -ResourceGroupName $BlueprintGlobalResourceGroupName -Name $UserAssignedIdentityName
Write-Host "`nUser Assigned Identity '$UserAssignedIdentityName' already exists" -ForegroundColor Cyan
$UserAssignedIdentity
}
$UserAssignedIdentityId = $UserAssignedIdentity.Id
$ScriptExecutionUserObjectID = $UserAssignedIdentity.PrincipalId
@ -486,33 +582,23 @@ if (-not($UAMIOwnerSubRoleCheck)){
Write-Host "User assigned identity '$UserAssignedIdentityName' already has 'Owner' role assigned at the subscription level" -ForegroundColor Cyan
$UAMIOwnerSubRoleCheck
}
#endregion
#region Grant the 'Blueprint Operator' subscription level role to the managed identity
Write-Host "Now checking if user assigned identity '$UserAssignedIdentityName' has 'Blueprint Operator' subscription level role assignment" -ForegroundColor Cyan
if (-not(Get-AzRoleAssignment -ResourceGroupName $BlueprintGlobalResourceGroupName -ObjectID ($UserAssignedIdentity).PrincipalId -RoleDefinitionName 'Blueprint Operator')) {
Write-Host "`User assigned identity '$UserAssignedIdentityName' does not currently have 'Blueprint Operator' subscription level role assignment" -ForegroundColor Cyan
Write-Host "Now assigning 'Blueprint Operator' role to '$UserAssignedIdentityName'" -ForegroundColor Cyan
New-AzRoleAssignment -ObjectId ($UserAssignedIdentity).PrincipalId -RoleDefinitionName 'Blueprint Operator' -Scope "/subscriptions/$AzureSubscriptionID"
#region Register the Azure Blueprint provider to the subscription, if not already registered
Write-Host "Now checking the 'Microsoft.Blueprint' provider, and registering if needed" -ForegroundColor Cyan
$BlueprintProviderRegistration = Get-AzResourceProvider -ListAvailable | Where-Object {($_.ProviderNamespace -EQ "Microsoft.Blueprint" -and $_.RegistrationState -EQ "Registered")}
if (-not($BlueprintProviderRegistration)) {
Write-Host "The 'Microsoft.Blueprint' provider is not currently registered. Now registering..." -ForegroundColor Cyan
Register-AzResourceProvider -ProviderNamespace 'Microsoft.Blueprint'
# adding a pause here until the 'Blueprint' provider is in the actual 'Registered' state
Do {
Write-Host "Pausing to ensure 'Blueprint' provider is in the 'registered' state. waiting 3 seconds..." -ForegroundColor Cyan
Start-Sleep -Seconds 3
} until (Get-AzResourceProvider -ListAvailable | Where-Object {($_.ProviderNamespace -EQ "Microsoft.Blueprint" -and $_.RegistrationState -EQ "Registered")} -ErrorAction SilentlyContinue)
Get-AzResourceProvider -ListAvailable | Where-Object {($_.ProviderNamespace -EQ "Microsoft.Blueprint" -and $_.RegistrationState -EQ "Registered")}
} else {
Write-Host "User assigned identity '$UserAssignedIdentityName' already has 'Blueprint Operator' role assigned at the subscription level" -ForegroundColor Cyan
Get-AzRoleAssignment -ResourceGroupName $BlueprintGlobalResourceGroupName -ObjectID ($UserAssignedIdentity).PrincipalId -RoleDefinitionName 'Blueprint Operator' -ErrorAction SilentlyContinue
}
#endregion
#region Assign Azure AD role 'Global Administrator' to the managed identity, to allow creation of AD objects during assignment, if not already assigned
$AADGlobalAdminRoleInfo = Get-AzureADMSRoleDefinition -Filter "displayName eq 'Global Administrator'"
$AADGlobalAdminRoleInfoId = $AADGlobalAdminRoleInfo.Id
$AADGlobalAdminRoleDisplayName = $AADGlobalAdminRoleInfo.displayName
Write-Host "`Assigning Azure AD role 'Global Administrator' to the managed identity" -ForegroundColor Cyan
if (-not(Get-AzureADMSRoleAssignment -Filter "principalID eq '$ScriptExecutionUserObjectID' and roleDefinitionId eq '$AADGlobalAdminRoleInfoId'")){
Write-Host "User assigned identity"$UserAssignedIdentity.name"does not have the"$AADGlobalAdminRoleInfo.displayName"role currently assigned." -ForegroundColor Cyan
Write-Host "Now assigning role to managed identity." -ForegroundColor Cyan
New-AzureADMSRoleAssignment -RoleDefinitionId $AADGlobalAdminRoleInfoId -PrincipalId $ScriptExecutionUserObjectID -DirectoryScopeId '/' -ErrorAction SilentlyContinue
} else {
Write-Host "User assigned identity '$UserAssignedIdentityName' already has the '$AADGlobalAdminRoleDisplayName' role assigned." -ForegroundColor Cyan
Get-AzureADMSRoleAssignment -Filter "principalID eq '$ScriptExecutionUserObjectID' and roleDefinitionId eq '$AADGlobalAdminRoleInfoId'"
Write-Host "The 'Microsoft.Blueprint' provider is already registered" -ForegroundColor Cyan
$BlueprintProviderRegistration
}
#endregion
@ -529,6 +615,52 @@ if (-not($BlueprintProviderList)) {
}
#endregion
#region Grant the 'Blueprint Operator' subscription level role to the managed identity
Write-Host "Now checking if user assigned identity '$UserAssignedIdentityName' has 'Blueprint Operator' subscription level role assignment" -ForegroundColor Cyan
$UAMIBlueprintOperatorRoleCheck = Get-AzUserAssignedIdentity -Name $UserAssignedIdentityName -ResourceGroupName $BlueprintGlobalResourceGroupName
if (-not($UAMIBlueprintOperatorRoleCheck)) {
Do {
Write-Host "User assigned identity '$UserAssignedIdentityName' is not currently available, waiting 3 seconds..." -ForegroundColor Cyan
Start-Sleep -Seconds 3
} until (Get-AzUserAssignedIdentity -Name $UserAssignedIdentityName -ResourceGroupName $BlueprintGlobalResourceGroupName -ErrorAction SilentlyContinue)
Write-Host "User Assigned Managed Identity '$UserAssignedIdentityName' is now available..." -ForegroundColor Cyan
}
$UAMIBlueprintOperatorRoleCheck2 = Get-AzRoleAssignment -ResourceGroupName $BlueprintGlobalResourceGroupName -ObjectID ($UserAssignedIdentity).PrincipalId -RoleDefinitionName 'Blueprint Operator'
if (-not($UAMIBlueprintOperatorRoleCheck2)){
Write-Host "Now checking if 'Blueprint Operator' role is currently assigned to '$UserAssignedIdentityName'" -ForegroundColor Cyan
Get-AzRoleAssignment -ResourceGroupName $BlueprintGlobalResourceGroupName -ObjectID ($UserAssignedIdentity).PrincipalId -RoleDefinitionName 'Blueprint Operator'
New-AzRoleAssignment -ObjectId ($UserAssignedIdentity).PrincipalId -RoleDefinitionName 'Blueprint Operator' -Scope "/subscriptions/$AzureSubscriptionID"
} else {
Write-Host "User assigned identity '$UserAssignedIdentityName' already has 'Blueprint Operator' role assigned at the subscription level" -ForegroundColor Cyan
Get-AzRoleAssignment -ResourceGroupName $BlueprintGlobalResourceGroupName -ObjectID ($UserAssignedIdentity).PrincipalId -RoleDefinitionName 'Blueprint Operator' -ErrorAction SilentlyContinue
}
#endregion
#region Assign Azure AD role 'Global Administrator' to the managed identity, to allow creation of AD objects during assignment, if not already assigned
$AADGlobalAdminRoleInfo = Get-AzureADMSRoleDefinition -Filter "displayName eq 'Global Administrator'"
$AADGlobalAdminRoleInfoId = $AADGlobalAdminRoleInfo.Id
$AADGlobalAdminRoleDisplayName = $AADGlobalAdminRoleInfo.displayName
Write-Host "`Assigning Azure AD role 'Global Administrator' to the managed identity" -ForegroundColor Cyan
$UAMIOwnerSubRoleCheck = Get-AzUserAssignedIdentity -Name $UserAssignedIdentityName -ResourceGroupName $BlueprintGlobalResourceGroupName -ErrorAction SilentlyContinue
if (-not($UAMIOwnerSubRoleCheck)){
Do {
Write-Host "Waiting 3 seconds for user assigned managed identity '$UserAssignedIdentityName' to become available for next operation..." -ForegroundColor Cyan
Start-Sleep -Seconds 3
} until (Get-AzUserAssignedIdentity -Name $UserAssignedIdentityName -ResourceGroupName $BlueprintGlobalResourceGroupName -ErrorAction SilentlyContinue)
}
if (-not(Get-AzureADMSRoleAssignment -Filter "principalID eq '$ScriptExecutionUserObjectID' and roleDefinitionId eq '$AADGlobalAdminRoleInfoId'")){
Write-Host "User assigned identity"$UserAssignedIdentity.name"does not have the"$AADGlobalAdminRoleInfo.displayName"role currently assigned." -ForegroundColor Cyan
Write-Host "Now assigning role to managed identity." -ForegroundColor Cyan
New-AzureADMSRoleAssignment -RoleDefinitionId $AADGlobalAdminRoleInfoId -PrincipalId $ScriptExecutionUserObjectID -DirectoryScopeId '/' -ErrorAction SilentlyContinue
} else {
Write-Host "User assigned identity '$UserAssignedIdentityName' already has the '$AADGlobalAdminRoleDisplayName' role assigned." -ForegroundColor Cyan
Get-AzureADMSRoleAssignment -Filter "principalID eq '$ScriptExecutionUserObjectID' and roleDefinitionId eq '$AADGlobalAdminRoleInfoId'"
}
#endregion
#region Register the 'Microsoft.AAD' provider to the subscription, if not already registered
Write-Host "Now checking the 'Microsoft.AAD' provider, and registering if needed" -ForegroundColor Cyan
$MicrosoftAADProviderCheck = Get-AzResourceProvider -ListAvailable | Where-Object {($_.ProviderNamespace -EQ "Microsoft.AAD" -and $_.RegistrationState -EQ "Registered")}

Просмотреть файл

@ -54,27 +54,48 @@ Param(
[switch] $PurgeKeyVault
)
#Trying to work around an issue where the modules were previously installed but don't report that way to PowerShell
Write-Verbose "Checking PowerShell modules needed to run this script"
if (-not(Get-Module -Name 'Az.Keyvault')) {
Import-Module -Name 'Az.Keyvault' -Force
}
if (-not(Get-Module -Name 'Az.Keyvault')) {
Install-Module 'Az.Keyvault' -Force
Import-Module -Name 'Az.Keyvault' -Force
}
if (-not(Get-Module -Name 'Az.Storage')) {
Import-Module -Name 'Az.Storage' -Force
}
if (-not(Get-Module -Name 'Az.Storage')) {
Install-Module 'Az.Storage' -Force
Import-Module -Name 'Az.Storage' -Force
}
if (-not(Get-Module -Name 'Az.Resources')) {
Import-Module -Name 'Az.Resources' -Force
}
if (-not(Get-Module -Name 'Az.Resources')) {
Install-Module 'Az.Resources' -Force
Import-Module -Name 'Az.Resources' -Force
}
if (-not(Get-Module -Name 'Az.OperationalInsights')) {
Import-Module -Name 'Az.OperationalInsights' -Force
}
if (-not(Get-Module -Name 'Az.OperationalInsights')) {
Install-Module 'Az.OperationalInsights' -Force
Import-Module -Name 'Az.OperationalInsights' -Force
}
if (-not(Get-Module -Name 'AzureAD')) {
Import-Module -Name 'AzureAD' -Force
}
if (-not(Get-Module -Name 'AzureAD')) {
Install-Module 'AzureAD' -Force
Import-Module -Name 'AzureAD' -Force
}
if (-not(Get-Module -Name 'Az.DesktopVirtualization')) {
Import-Module 'Az.DesktopVirtualization' -Force
}
if (-not(Get-Module -Name 'Az.DesktopVirtualization')) {
Install-Module 'Az.DesktopVirtualization' -Force
Import-Module 'Az.DesktopVirtualization' -Force
}

Просмотреть файл

@ -19,8 +19,10 @@ Param(
[string] $evdvm_name_prefix,
[Parameter(Mandatory=$true)]
[string] $vmNumberOfInstances
[string] $vmNumberOfInstances,
[Parameter(Mandatory=$true)]
[string] $keyvaultname
)
#region Install RSAT-AD Tools, GP Tools, setup working folders, and install 'Az' PowerShell modules
Install-WindowsFeature -name GPMC
@ -51,8 +53,10 @@ $Scriptblock = {
[string] $evdvm_name_prefix,
[Parameter(Mandatory=$true,Position=6)]
[string] $vmNumberOfInstances
[string] $vmNumberOfInstances,
[Parameter(Mandatory=$true,Position=7)]
[string] $keyvaultname
)
Start-Transcript -OutputDirectory C:\Windows\Temp
@ -150,7 +154,7 @@ Connect-AzAccount -Identity -Environment $AzureEnvironmentName
# Download AVD post-install group policy settings zip file, and expand it
$CTempPath = 'C:\Temp'
New-Item -ItemType Directory -Path "$CTempPath" -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Path $CTempPath -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Path "$CTempPath\Software" -ErrorAction SilentlyContinue
$AVDPostInstallGPSettingsZip = "$CTempPath\AVD_PostInstall_GP_Settings.zip"
$ZipFileURI = "$ScriptURI/AVD_PostInstall_GP_Settings.zip"
@ -211,7 +215,7 @@ $AVDComputersOU = New-ADOrganizationalUnit -Name 'AVD Computers' -DisplayName 'A
New-GPLink -Target $AVDComputersOU.DistinguishedName -Name $AVDPolicy.DisplayName -LinkEnabled Yes
# Get credentials and use those to move AVD session hosts to their new OU
$KeyVault = Get-AzKeyVault -VaultName "*-sharedsvcs-kv"
$KeyVault = Get-AzKeyVault -VaultName $keyvaultname
$DAUserUPN = (Get-AzADGroup -DisplayName "AAD DC Administrators" | Get-AzADGroupMember).UserPrincipalName
$DAUserName = $DAUserUPN.Split('@')[0]
$DAPass = (Get-AzKeyVaultSecret -VaultName $keyvault.VaultName -name $DAUserName).SecretValue
@ -270,7 +274,7 @@ for ($i = 1; $i -le $vmNumberOfInstances ; $i++) {
$s = New-PSSession -ComputerName $VMComputerName
Invoke-Command -Session $s -ScriptBlock {
gpupdate /force
shutdown /r /f /t 15
shutdown /r /f /t 60
}
Remove-PSSession -Session $s
}
@ -287,7 +291,7 @@ for ($i = 1; $i -le $vmNumberOfInstances ; $i++) {
Connect-AzAccount -Identity -Environment $AzureEnvironmentName
#Create a DAuser context, using password from Key Vault
$KeyVault = Get-AzKeyVault -VaultName "*-sharedsvcs-kv"
$KeyVault = Get-AzKeyVault -VaultName $keyvaultname
$DAUserUPN = (Get-AzADGroup -DisplayName "AAD DC Administrators" | Get-AzADGroupMember).UserPrincipalName
$DAUserName = $DAUserUPN.Split('@')[0]
$DAPass = (Get-AzKeyVaultSecret -VaultName $keyvault.VaultName -name $DAUserName).SecretValue
@ -311,7 +315,7 @@ Get-AzContext | Out-File -append c:\windows\temp\outercontext.txt
klist tickets | Out-File -append c:\windows\temp\outercontext.txt
#Run the $scriptblock in the DAuser context
Invoke-Command -ConfigurationName DASessionConf -ComputerName $env:COMPUTERNAME -ScriptBlock $Scriptblock -ArgumentList $ResourceGroupName,$StorageAccountName,$ScriptURI,$AzureEnvironmentName,$AzureStorageFQDN,$evdvm_name_prefix,$vmNumberOfInstances
Invoke-Command -ConfigurationName DASessionConf -ComputerName $env:COMPUTERNAME -ScriptBlock $Scriptblock -ArgumentList $ResourceGroupName,$StorageAccountName,$ScriptURI,$AzureEnvironmentName,$AzureStorageFQDN,$evdvm_name_prefix,$vmNumberOfInstances,$keyvaultname
#Clean up DAuser context
Unregister-PSSessionConfiguration -Name DASessionConf -Force