Azure Virtual Desktop deploy script
windows
Azure
Connect-AzAccount
$subscriptionId = "your-subscription-id"
$resourceGroupName = "AVDResourceGroup"
$location = "EastUS"
$vnetName = "AVDVNet"
$addressSpace = "10.0.0.0/16"
$subnetPrefix = "10.0.0.0/24"
$nsgName = "AVDNSG"
$storageAccountName = "fslogixstorage$(Get-Random)"
$storageSku = "Standard_LRS"
$fileShareName = "fslogixprofiles"
$dcVMName = "ADDCVM"
$dcVMSize = "Standard_DS1_v2"
$dcAdminUsername = "dcadmin"
$dcAdminPassword = ConvertTo-SecureString "YourDCAdminPassword123!" -AsPlainText -Force
$domainName = "contoso.com"
$domainNetbiosName = "CONTOSO"
$vmName = "AVDWin11VM"
$vmSize = "Standard_D2s_v3"
$adminUsername = "azureuser"
$adminPassword = ConvertTo-SecureString "YourSecurePassword123!" -AsPlainText -Force
$hostPoolName = "AVDHostPool"
$hostPoolType = "Pooled"
$appGroupName = "AVDAppGroup"
$workspaceName = "AVDWorkspace"
$registrationTokenExpiration = (Get-Date).AddDays(7)
$userPrincipalName = "user@contoso.com"
Select-AzSubscription -SubscriptionId $subscriptionId
New-AzResourceGroup -Name $resourceGroupName -Location $location
$vnet = New-AzVirtualNetwork -Name $vnetName -ResourceGroupName $resourceGroupName `
-Location $location -AddressPrefix $addressSpace
$dcSubnetName = "DomainControllerSubnet"
Add-AzVirtualNetworkSubnetConfig -Name $dcSubnetName -AddressPrefix "10.0.1.0/24" -VirtualNetwork $vnet
$vmSubnetName = "SessionHostSubnet"
Add-AzVirtualNetworkSubnetConfig -Name $vmSubnetName -AddressPrefix $subnetPrefix -VirtualNetwork $vnet
$vnet | Set-AzVirtualNetwork
$nsg = New-AzNetworkSecurityGroup -Name $nsgName -ResourceGroupName $resourceGroupName -Location $location
$nsgRuleRDP = New-AzNetworkSecurityRuleConfig -Name "AllowRDP" -Protocol "Tcp" -Direction "Inbound" `
-Priority 1000 -SourceAddressPrefix "*" -SourcePortRange "*" -DestinationAddressPrefix "*" `
-DestinationPortRange 3389 -Access "Allow"
$nsg.SecurityRules.Add($nsgRuleRDP)
$nsg | Set-AzNetworkSecurityGroup
$storageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName `
-Location $location -SkuName $storageSku -Kind "StorageV2"
$storageContext = $storageAccount.Context
New-AzStorageShare -Name $fileShareName -Context $storageContext
$dcPublicIP = New-AzPublicIpAddress -Name "$dcVMName-PIP" -ResourceGroupName $resourceGroupName `
-Location $location -AllocationMethod Static -Sku Basic
$dcSubnet = Get-AzVirtualNetworkSubnetConfig -Name $dcSubnetName -VirtualNetwork $vnet
$dcNIC = New-AzNetworkInterface -Name "$dcVMName-NIC" -ResourceGroupName $resourceGroupName `
-Location $location -SubnetId $dcSubnet.Id -PublicIpAddressId $dcPublicIP.Id -NetworkSecurityGroupId $nsg.Id
$dcVMConfig = New-AzVMConfig -VMName $dcVMName -VMSize $dcVMSize
$dcVMConfig = Set-AzVMOperatingSystem -VM $dcVMConfig -Windows -ComputerName $dcVMName `
-Credential (New-Object System.Management.Automation.PSCredential ($dcAdminUsername, $dcAdminPassword)) `
-ProvisionVMAgent -EnableAutoUpdate
$dcVMConfig = Set-AzVMSourceImage -VM $dcVMConfig -PublisherName "MicrosoftWindowsServer" `
-Offer "WindowsServer" -Skus "2019-Datacenter" -Version "latest"
$dcVMConfig = Add-AzVMNetworkInterface -VM $dcVMConfig -Id $dcNIC.Id
New-AzVM -ResourceGroupName $resourceGroupName -Location $location -VM $dcVMConfig
$promoteDCScript = @"
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
Import-Module ADDSDeployment
Install-ADDSForest -DomainName '$domainName' -DomainNetbiosName '$domainNetbiosName' `
-SafeModeAdministratorPassword (ConvertTo-SecureString 'YourDCSafeModePassword!' -AsPlainText -Force) `
-InstallDNS -Force
"@
$dcScriptPath = "C:\\Temp\\PromoteDC.ps1"
$promoteDCScript | Out-File -FilePath $dcScriptPath -Encoding ASCII
Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $dcVMName -Location $location `
-Name "PromoteDC" -FileUri "" -Run "PromoteDC.ps1"
$vmPublicIP = New-AzPublicIpAddress -Name "$vmName-PIP" -ResourceGroupName $resourceGroupName `
-Location $location -AllocationMethod Static -Sku Basic
$vmSubnet = Get-AzVirtualNetworkSubnetConfig -Name $vmSubnetName -VirtualNetwork $vnet
$vmNIC = New-AzNetworkInterface -Name "$vmName-NIC" -ResourceGroupName $resourceGroupName `
-Location $location -SubnetId $vmSubnet.Id -PublicIpAddressId $vmPublicIP.Id -NetworkSecurityGroupId $nsg.Id
$imagePublisher = "MicrosoftWindowsDesktop"
$imageOffer = "office-365"
$imageSku = "win11-22h2-avd"
$imageVersion = "latest"
$vmConfig = New-AzVMConfig -VMName $vmName -VMSize $vmSize
$vmConfig = Set-AzVMOperatingSystem -VM $vmConfig -Windows -ComputerName $vmName `
-Credential (New-Object System.Management.Automation.PSCredential ($adminUsername, $adminPassword)) `
-ProvisionVMAgent -EnableAutoUpdate
$vmConfig = Set-AzVMSourceImage -VM $vmConfig -PublisherName $imagePublisher `
-Offer $imageOffer -Skus $imageSku -Version $imageVersion
$vmConfig = Add-AzVMNetworkInterface -VM $vmConfig -Id $vmNIC.Id
New-AzVM -ResourceGroupName $resourceGroupName -Location $location -VM $vmConfig
$domainJoinCred = New-Object System.Management.Automation.PSCredential ("$domainName\$dcAdminUsername", $dcAdminPassword)
Set-AzVMADDomainExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name "joindomain" `
-Location $location -DomainName $domainName -Credential $domainJoinCred
$installFSLScript = @"
New-Item -ItemType Directory -Path C:\Temp -Force
Invoke-WebRequest -Uri 'https://aka.ms/fslogix_download' -OutFile 'C:\Temp\FSLogixAppsSetup.exe'
Start-Process 'C:\Temp\FSLogixAppsSetup.exe' -ArgumentList '/quiet /norestart' -Wait
"@
$installFSLScriptPath = "C:\\Temp\\InstallFSLogix.ps1"
$installFSLScript | Out-File -FilePath $installFSLScriptPath -Encoding ASCII
Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Location $location `
-Name "InstallFSLogix" -FileUri "" -Run "InstallFSLogix.ps1"
$configFSLScript = @"
New-Item -Path 'HKLM:\SOFTWARE\FSLogix' -Force
New-Item -Path 'HKLM:\SOFTWARE\FSLogix\Profiles' -Force
Set-ItemProperty -Path 'HKLM:\SOFTWARE\FSLogix\Profiles' -Name 'Enabled' -Type DWord -Value 1
Set-ItemProperty -Path 'HKLM:\SOFTWARE\FSLogix\Profiles' -Name 'VHDLocations' -Type MultiString -Value '\\$storageAccountName.file.core.windows.net\$fileShareName'
Set-ItemProperty -Path 'HKLM:\SOFTWARE\FSLogix\Profiles' -Name 'AccessNetworkAsComputerObject' -Type DWord -Value 0
Set-ItemProperty -Path 'HKLM:\SOFTWARE\FSLogix\Profiles' -Name 'IsDynamic' -Type DWord -Value 1
$SecureStorageKey = ConvertTo-SecureString -String "" -AsPlainText -Force
cmdkey /add:"$storageAccountName.file.core.windows.net" /user:"Azure\$storageAccountName" /pass:$SecureStorageKey
"@
$configFSLScriptPath = "C:\\Temp\\ConfigureFSLogix.ps1"
$configFSLScript | Out-File -FilePath $configFSLScriptPath -Encoding ASCII
Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Location $location `
-Name "ConfigureFSLogix" -FileUri "" -Run "ConfigureFSLogix.ps1"
$hostPool = New-AzWvdHostPool -ResourceGroupName $resourceGroupName -Name $hostPoolName -Location $location `
-HostPoolType $hostPoolType -LoadBalancerType "BreadthFirst" -PreferredAppGroupType "Desktop"
$registrationInfo = New-AzWvdRegistrationInfo -ResourceGroupName $resourceGroupName -HostPoolName $hostPoolName `
-ExpirationTime $registrationTokenExpiration
$registrationToken = $registrationInfo.Token
$registerAVDScript = @"
New-Item -ItemType Directory -Path C:\Temp -Force
Invoke-WebRequest -Uri 'https://aka.ms/wvd/agents' -OutFile 'C:\Temp\AVDAgent.msi'
Start-Process 'msiexec.exe' -ArgumentList '/i C:\Temp\AVDAgent.msi /quiet' -Wait
Invoke-WebRequest -Uri 'https://aka.ms/wvd/bootloader' -OutFile 'C:\Temp\AVDStack.msi'
Start-Process 'msiexec.exe' -ArgumentList '/i C:\Temp\AVDStack.msi /quiet' -Wait
& 'C:\Program Files\Microsoft RDInfra\RDAgent\RDInfraAgent.exe' /joinRdbroker $registrationToken
"@
$registerAVDScriptPath = "C:\\Temp\\RegisterAVD.ps1"
$registerAVDScript | Out-File -FilePath $registerAVDScriptPath -Encoding ASCII
Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Location $location `
-Name "RegisterAVD" -FileUri "" -Run "RegisterAVD.ps1"
$appGroup = New-AzWvdApplicationGroup -ResourceGroupName $resourceGroupName -HostPoolName $hostPoolName `
-Location $location -Name $appGroupName -ApplicationGroupType "Desktop"
New-AzWvdDesktopAssignment -ResourceGroupName $resourceGroupName -ApplicationGroupName $appGroupName `
-Name $userPrincipalName
$workspace = New-AzWvdWorkspace -ResourceGroupName $resourceGroupName -Name $workspaceName -Location $location
New-AzWvdWorkspaceApplicationGroupAssociation -ResourceGroupName $resourceGroupName `
-WorkspaceName $workspaceName -ApplicationGroupName $appGroupName
Write-Host "Azure Virtual Desktop environment setup is complete."
Write-Host "Please ensure all placeholders are replaced with your actual values before running the script."