Deploying Azure Virtual Desktop Session Host using Bicep only
Deploying Azure Virtual Desktop Session Host using Bicep.
Welcome back to my blog!
It’s been a while since I last wrote a blog. My previous one was about Azure Kubernetes Service. In the meantime, I’ve been working on a few Azure Virtual Desktop deployments and found out that we can actually deploy session hosts entirely using Bicep. This also means that if the environment doesn’t need any extra configuration and customization in the sessionhost, the whole process can pretty much be handled with Bicep alone. That’s why I wanted to share this with you and of course a big shoutout to my friend and colleague Simon Lee from BuildWithCaffeine for pointing me in the right direction.
Of course, you can also combine this with an Azure Pipeline, just like I’ve covered in my previous blogs. But keeping everything in Bicep without relying on custom scripts makes the whole process a lot cleaner and easier to manage.
How are we gonna start?
We will kick things off with an environment that’s already up and running in my Azure subscription. This setup was deployed using the same Bicep templates I shared in my earlier blogs. From there, I’ll walk you through how we can extend that setup and get session hosts fully deployed with just Bicep, no extra scripts needed.
You might be thinking: “No extra scripts at all?” Fair enough we do still need a single PowerShell deployment script to run the Bicep.
We are using the Azure Verified Modules, built by the community and following Bicep best practices. No need for any custom Bicep modules here.
So, we are working with three files here: a deployment script that calls the Bicep file and the Bicep parameter file. Of course, you’re free to tweak these to fit your own environment.
One thing worth mentioning I am using passwords directly in the parameter file for this demo. Ideally, for security reasons, you’d want to use Key Vault instead because that's best practice. But to keep things simple, I’m sticking with a hardcoded password here.
In my next blog, I’ll show you how to do this properly with Key Vault.
The Bicep file
Since this Bicep file combines calling an existing environment with creating a new session host, let me walk you through how that works in practice.
We are using the Bicep Azure Verified Modules, but when it comes to referencing existing Bicep resources, you’ll need to use a different approach like in the example below:
In this example, you can see that I’m calling an existing resource group using the resource module and the existing parameter. I’m doing this in the Bicep file for the environment I already have set up.
1@description('Reference to the existing existing hostpool')
2resource existingResourceGroup 'Microsoft.Resources/resourceGroups@2025-04-01' existing = {
3 name: existingResourceGroupName
4 scope: subscription(existingSubscriptionId)
5}
Let’s take a look at the full Bicep file. This file handles calling multiple existing resources, so you’ll need to fill in the existing parameters in your Bicep parameter file (we will get to that in a bit). After it references all the existing resources such as Subscription, Resource Group, Virtual Network, Subnet, Hostpool, Shared Image Gallery, and the existing versions of the images, it will create a VM based on the existing Image Version in the Shared Image Gallery.
1targetScope = 'subscription'
2
3param updatedBy string
4
5@allowed([
6 'test'
7 'dev'
8 'prod'
9 'acc'
10])
11param environmentType string
12
13param subscriptionId string
14
15@description('Unique identifier for the deployment')
16param deploymentGuid string = newGuid()
17
18@description('Product Type: example avd.')
19@allowed([
20 'avd'
21])
22param productType string
23
24@description('Azure Region to deploy the resources in.')
25@allowed([
26 'westeurope'
27 'northeurope'
28 'ukwest'
29 'uksouth'
30 'francecentral'
31 'francesouth'
32 'switzerlandnorth'
33 'switzerlandwest'
34 'germanywestcentral'
35 'germanynorth'
36 'centralus'
37 'eastus'
38 'swedencentral'
39 'swedensouth'
40])
41param location string
42
43@description('Location shortcode. Used for end of resource names.')
44param locationShortCode string
45
46@description('Add tags as required as Name:Value')
47param tags object = {
48 Environment: environmentType
49 LastUpdatedOn: utcNow('d')
50 LastDeployedBy: updatedBy
51}
52
53param existingSubscriptionId string
54param existingResourceGroupName string
55param existingHostpoolName string
56param existingVnetName string
57param existingSubnetName string
58param existingGalleryName string
59param existingVersionName string
60param existingVersionNumber string
61
62@minValue(1)
63@description('Number of session hosts to deploy')
64param sessionHostCount int
65
66@description('Number of session hosts to deploy')
67param sessionHostname string
68
69@description('local admin username for the session host VMs')
70param sessionHostUsername string
71
72@secure()
73@description('local admin password for the session host VMs')
74param sessionHostPassword string
75
76@description('OS type for the session host VM')
77param osType string
78
79@description('vm size for the session host VM')
80param vmSize string
81
82@description('license type for the session host VM')
83param licenseType string
84
85@description('disk size in GB for the session host VM')
86param diskSizeGB int
87
88@description('disk sku for the session host VM')
89param diskStorageAccountType string
90
91@description('Username for the domain join user account')
92param domainJoinUsername string
93
94@secure()
95@description('Password for the domain join user account')
96param domainJoinPassword string
97
98@description('Domain name for the domain join user account')
99param domainName string
100
101@description('Reference to the existing existing hostpool')
102resource existingResourceGroup 'Microsoft.Resources/resourceGroups@2025-04-01' existing = {
103 name: existingResourceGroupName
104 scope: subscription(existingSubscriptionId)
105}
106
107@description('Reference to the existing existing hostpool')
108resource existingResourceHostpool 'Microsoft.DesktopVirtualization/hostPools@2024-08-08-preview' existing = {
109 name: existingHostpoolName
110 scope: resourceGroup(existingSubscriptionId, existingResourceGroupName)
111}
112
113@description('Reference to the existing existing hostppol')
114resource existingResourceVnet 'Microsoft.Network/virtualNetworks@2024-07-01' existing = {
115 name: existingVnetName
116 scope: resourceGroup(existingSubscriptionId, existingResourceGroupName)
117}
118
119@description('Reference to the existing existing hostppol')
120resource existingResourceSubnet 'Microsoft.Network/virtualNetworks/subnets@2024-07-01' existing = {
121 name: existingSubnetName
122 parent: existingResourceVnet
123}
124
125// Loop to create multiple session hosts
126module createSessionHost 'br/public:avm/res/compute/virtual-machine:0.18.0' = [
127 for i in range(0, sessionHostCount): {
128 scope: resourceGroup(existingSubscriptionId, existingResourceGroupName)
129 name: 'avd-${i}'
130 params: {
131 name: '${sessionHostname}-${i + 1}'
132 location: location
133 osType: osType
134 vmSize: vmSize
135 availabilityZone: 1
136 bootDiagnostics: true
137 secureBootEnabled: true
138 licenseType: licenseType
139 enableAutomaticUpdates: true
140 encryptionAtHost: true
141 securityType: 'TrustedLaunch'
142 adminUsername: sessionHostUsername
143 adminPassword: sessionHostPassword
144 managedIdentities: {
145 systemAssigned: true
146 }
147 imageReference: {
148 id: '/subscriptions/${existingSubscriptionId}/resourceGroups/${existingResourceGroupName}/providers/Microsoft.Compute/galleries/${existingGalleryName}/images/${existingVersionName}/versions/${existingVersionNumber}'
149 }
150 osDisk: {
151 caching: 'ReadWrite'
152 diskSizeGB: diskSizeGB
153 managedDisk: {
154 storageAccountType: diskStorageAccountType
155 }
156 }
157 nicConfigurations: [
158 {
159 name: 'nic-avd-${i + 1}'
160 enableAcceleratedNetworking: true
161 ipConfigurations: [
162 {
163 name: 'ipconfig-${deploymentGuid}-${i + 1}'
164 subnetResourceId: existingResourceSubnet.id
165 }
166 ]
167 }
168 ]
169
170 extensionDomainJoinConfig: {
171 enabled: true
172 settings: {
173 name: domainName
174 user: domainJoinUsername
175
176 restart: true
177 options: 3
178 }
179 }
180 extensionDomainJoinPassword: domainJoinPassword
181
182 extensionHostPoolRegistration: {
183 enabled: true
184 modulesUrl: 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip'
185 configurationFunction: 'Configuration.ps1\\AddSessionHost'
186 hostPoolName: existingResourceHostpool.name
187 registrationInfoToken: existingResourceHostpool.listRegistrationTokens().value[0].token
188 }
189 tags: tags
190 }
191 dependsOn: [existingResourceGroup]
192 }
193]
For this, it uses the public module available from the Azure Verified Modules. This will deploy individual Virtual Machines that’s looped through: want one VM? You get one. Want ten? You get ten.
In the module, I use two extensions. First, EnableHostPoolRegistration, which needs the moduleURL where the AVD templates live and the PowerShell script that handles the configuration behind the scenes. Both are available in the same location and can be copied as-is. I also specify that it should pull an existing token from the hostpool using:
existingResourceHostpool.listRegistrationTokens().value[0].token
The session host can’t be added when we don't use a registration token.
It’s also worth mentioning that I use an extension to domain-join the VM. To make this work, of course, you’ll need a domain controller or ADDS in place.
The Bicep param file
The Bicep parameter file basically holds the values we want to use for the Bicep deployment. Some values I like to keep fixed in the Bicep file itself because they don’t need to be changed, such as enableSecureBoot or Bootdiagnostics, which should always be set to true when building it WAF alligned.
But there are values you’ll want to tweak, like the SKU size or the disk SKU. another example, if you’re deploying a Windows 2022 edition on AVD, you’ll need to adjust the license type to Windows_Server.
Of course, you’re free to change these values yourself, and if you want to include more settings in your Bicep parameter file, you can absolutely do that.
1using 'deploy-sessionhost.bicep'
2
3//parameters for the deployment.
4param updatedBy = ''
5param subscriptionId = ''
6param environmentType = 'test'
7param location = 'westeurope'
8param locationShortCode = 'weu'
9param productType = 'avd'
10
11//Paramameters for the existing AVD environtment.
12param existingSubscriptionId = ''
13param existingResourceGroupName = 'rg-avd-prod-weu'
14param existingHostpoolName = 'vdpool-avd-prod-weu'
15param existingVnetName = 'vnet-avd-prod-weu'
16param existingSubnetName = 'snet-avd'
17param existingGalleryName = 'galavdprodweu'
18param existingVersionName = 'img-avd-prod-weu'
19param existingVersionNumber = '2025.07.03'
20
21//Parameters for the local user account session host VM's
22param sessionHostname = 'pof-avd'
23param sessionHostUsername = 'yourusername'
24param sessionHostPassword = 'yourpassword'
25
26//Parameters for the session host VM's
27param osType = 'Windows'
28param vmSize = 'Standard_DS2_v2'
29param licenseType = 'Windows_Client'
30param diskSizeGB = 128
31param diskStorageAccountType = 'Premium_LRS'
32
33///Number of session hosts to deploy
34param sessionHostCount = 2
35
36//Parameters for the domain join user account
37param domainJoinPassword = ''
38param domainJoinUsername = 'yourdomain\\youraccount'
39param domainName = 'your.domain'
The version is set by using the following line in the Bicep file: So you only have to fill the existingVersionNumber
id: '/subscriptions/${existingSubscriptionId}/resourceGroups/${existingResourceGroupName}/providers/Microsoft.Compute/galleries/${existingGalleryName}/images/${existingVersionName}/versions/${existingVersionNumber}'
The Deployment script
The deployment script is basically the same one we always use for deploying Bicep files, with just a few small tweaks. First, it checks and updates all versions that are uses like Azure CLI, Bicep, and Desktop Virtualization. We also set the subscription and check if the account that runs the script has the right access, then set the necessary variables.
Next, the script makes sure all required files are present. After that, it creates a registration token using the az desktopvirtualization module, this token is valid for up to 2 hours so that the Bicep deployment can run smoothly and it is able to add sessionhosts.
And of course it is running with a What-if statement so you can control your deployment.
1param(
2 [Parameter(Mandatory = $true)][string] $subscriptionID = "",
3 [Parameter(Mandatory = $true)][ValidateSet("northeurope", "westeurope")][string] $location = "",
4 [ValidateSet("avd")][string][Parameter(Mandatory = $true, ParameterSetName = 'Default')] $productType = "",
5 [Parameter(Mandatory = $true, Position = 3)] [validateSet("prod", "acc", "dev", "test")] [string] $environmentType = "",
6 [switch] $deploy,
7 [switch] $updateBicep
8)
9
10# Ensure parameters are captured
11Write-Host "Subscription ID: $subscriptionID"
12Write-Host "Location: $location"
13Write-Host "Product Type: $productType"
14Write-Host "Environment Type: $environmentType"
15
16$deploymentID = (New-Guid).Guid
17
18<# Validate Prerequisites #>
19Write-Host "Validating prerequisites..." -ForegroundColor Cyan
20
21# Validate Azure CLI is available
22if (-not (Get-Command az -ErrorAction SilentlyContinue)) {
23 Write-Host "Azure CLI is not installed or not in PATH. Please install Azure CLI first." -ForegroundColor Red
24 Write-Host "Download from: https://aka.ms/installazurecliwindows" -ForegroundColor Yellow
25 exit 1
26}
27
28# Check Azure CLI version
29try {
30 $azVersion = az version --query '"azure-cli"' --output tsv 2>$null
31 if ($azVersion) {
32 Write-Host "Azure CLI version: $azVersion" -ForegroundColor Green
33 }
34} catch {
35 Write-Host "Warning: Unable to determine Azure CLI version" -ForegroundColor Yellow
36}
37
38<# Check and Update Bicep CLI #>
39Write-Host "Checking Bicep CLI..." -ForegroundColor Cyan
40
41# Check if Bicep is installed
42$bicepInstalled = $false
43try {
44 $bicepVersion = az bicep version --output tsv 2>$null
45 if ($bicepVersion) {
46 Write-Host "Current Bicep CLI version: $bicepVersion" -ForegroundColor Green
47 $bicepInstalled = $true
48 }
49} catch {
50 Write-Host "Bicep CLI not found or not accessible." -ForegroundColor Yellow
51}
52
53# Install or update Bicep
54if (-not $bicepInstalled) {
55 Write-Host "Installing Bicep CLI..." -ForegroundColor Yellow
56 try {
57 az bicep install
58 if ($LASTEXITCODE -eq 0) {
59 Write-Host "Bicep CLI installed successfully." -ForegroundColor Green
60 $bicepVersion = az bicep version --output tsv 2>$null
61 Write-Host "Installed Bicep CLI version: $bicepVersion" -ForegroundColor Green
62 } else {
63 Write-Host "Failed to install Bicep CLI." -ForegroundColor Red
64 exit 1
65 }
66 } catch {
67 Write-Host "Error installing Bicep CLI: $($_.Exception.Message)" -ForegroundColor Red
68 exit 1
69 }
70} elseif ($updateBicep) {
71 Write-Host "Updating Bicep CLI to latest version..." -ForegroundColor Yellow
72 try {
73 az bicep upgrade
74 if ($LASTEXITCODE -eq 0) {
75 Write-Host "Bicep CLI updated successfully." -ForegroundColor Green
76 $newBicepVersion = az bicep version --output tsv 2>$null
77 Write-Host "Updated Bicep CLI version: $newBicepVersion" -ForegroundColor Green
78 } else {
79 Write-Host "Failed to update Bicep CLI." -ForegroundColor Red
80 }
81 } catch {
82 Write-Host "Error updating Bicep CLI: $($_.Exception.Message)" -ForegroundColor Red
83 }
84} else {
85 # Check for updates and auto-update if available
86 Write-Host "Checking for Bicep CLI updates..." -ForegroundColor Cyan
87 try {
88 $updateCheck = az bicep list-versions --output json | ConvertFrom-Json
89 if ($updateCheck -and $updateCheck.Count -gt 0) {
90 $latestVersion = $updateCheck[0]
91 if ($bicepVersion -ne $latestVersion) {
92 Write-Host "Bicep CLI update available: $latestVersion (current: $bicepVersion)" -ForegroundColor Yellow
93 Write-Host "Auto-updating Bicep CLI to latest version..." -ForegroundColor Yellow
94
95 az bicep upgrade
96 if ($LASTEXITCODE -eq 0) {
97 $newBicepVersion = az bicep version --output tsv 2>$null
98 Write-Host "Bicep CLI updated successfully to version: $newBicepVersion" -ForegroundColor Green
99 } else {
100 Write-Host "Failed to auto-update Bicep CLI. Continuing with current version." -ForegroundColor Yellow
101 }
102 } else {
103 Write-Host "Bicep CLI is up to date." -ForegroundColor Green
104 }
105 }
106 } catch {
107 Write-Host "Could not check for Bicep CLI updates. Continuing with current version." -ForegroundColor Yellow
108 }
109}
110# Check if Az.DesktopVirtualization module is installed
111Write-Host "Checking for Az.DesktopVirtualization PowerShell module..." -ForegroundColor Cyan
112if (-not (Get-Module -ListAvailable -Name Az.DesktopVirtualization)) {
113 Write-Host "Az.DesktopVirtualization module not found. Installing..." -ForegroundColor Yellow
114 try {
115 Install-Module -Name Az.DesktopVirtualization -Force -Scope CurrentUser -AllowClobber
116 Write-Host "Az.DesktopVirtualization module installed successfully." -ForegroundColor Green
117 } catch {
118 Write-Host "Failed to install Az.DesktopVirtualization module: $($_.Exception.Message)" -ForegroundColor Red
119 exit 1
120 }
121} else {
122 Write-Host "Az.DesktopVirtualization module is already installed." -ForegroundColor Green
123}
124<# Set Subscription Context #>
125Write-Host "Setting subscription context..." -ForegroundColor Cyan
126az account set --subscription $subscriptionID --output none
127if ($LASTEXITCODE -ne 0) {
128 Write-Host "Failed to set subscription context. Please verify the subscription ID and your access." -ForegroundColor Red
129 Write-Host "Please ensure you are logged in with 'az login' and have access to subscription: $subscriptionID" -ForegroundColor Yellow
130 exit 1
131}
132
133<# Retrieve Account Information with Error Handling #>
134Write-Host "Retrieving account information..." -ForegroundColor Cyan
135$accountInfo = az account show --output json 2>&1
136if ($LASTEXITCODE -ne 0) {
137 Write-Host "Failed to retrieve account information. Error: $accountInfo" -ForegroundColor Red
138 Write-Host "Please ensure you are logged in to Azure CLI with 'az login'" -ForegroundColor Yellow
139 Write-Host "If you're already logged in, try: az account clear && az login" -ForegroundColor Yellow
140 exit 1
141}
142
143try {
144 $accountJson = $accountInfo | ConvertFrom-Json -ErrorAction Stop
145 if ($accountJson.user -and $accountJson.user.name) {
146 $updatedBy = $accountJson.user.name
147 Write-Host "Successfully authenticated as: $updatedBy" -ForegroundColor Green
148 } else {
149 Write-Host "Warning: Unable to retrieve user name from account information." -ForegroundColor Yellow
150 $updatedBy = "Unknown User"
151 }
152} catch {
153 Write-Host "Failed to parse account information. Raw output: $accountInfo" -ForegroundColor Red
154 Write-Host "Error details: $($_.Exception.Message)" -ForegroundColor Red
155 Write-Host "Please try the following steps:" -ForegroundColor Yellow
156 Write-Host "1. Run 'az login' to authenticate with Azure CLI" -ForegroundColor Yellow
157 Write-Host "2. Run 'az account set --subscription $subscriptionID' to set the correct subscription" -ForegroundColor Yellow
158 Write-Host "3. Run 'az account show' to verify your authentication status" -ForegroundColor Yellow
159 exit 1
160}
161
162<# Validate Subscription Access #>
163Write-Host "Validating subscription access..." -ForegroundColor Cyan
164$currentSub = az account show --query id --output tsv 2>&1
165if ($LASTEXITCODE -ne 0 -or $currentSub -ne $subscriptionID) {
166 Write-Host "Subscription validation failed. Expected: $subscriptionID, Current: $currentSub" -ForegroundColor Red
167 exit 1
168}
169Write-Host "Subscription validation successful: $subscriptionID" -ForegroundColor Green
170
171<# Set Variables #>
172$location = $location.ToLower() -replace " ", ""
173
174$LocationShortCodeMap = @{
175 "westeurope" = "weu";
176 "northeurope" = "neu";
177}
178
179$locationShortCode = $LocationShortCodeMap.$location
180
181<# Validate Required Files #>
182Write-Host "Validating required files..." -ForegroundColor Cyan
183$requiredFiles = @("./deploy-sessionhost.bicep", "./deploy-sessionhosts.bicepparam")
184foreach ($file in $requiredFiles) {
185 if (-not (Test-Path $file)) {
186 Write-Host "Required file not found: $file" -ForegroundColor Red
187 exit 1
188 }
189}
190Write-Host "All required files found." -ForegroundColor Green
191
192<# Validate Bicep Template #>
193Write-Host "Validating Bicep template..." -ForegroundColor Cyan
194try {
195 az bicep build --file ./deploy-sessionhost.bicep --stdout > $null
196 if ($LASTEXITCODE -eq 0) {
197 Write-Host "Bicep template validation successful." -ForegroundColor Green
198 } else {
199 Write-Host "Bicep template validation failed. Please check your template." -ForegroundColor Red
200 exit 1
201 }
202} catch {
203 Write-Host "Error validating Bicep template: $($_.Exception.Message)" -ForegroundColor Red
204 exit 1
205}
206
207<# Generate Registration Token for Azure Virtual Desktop Host Pool #>
208Write-Host "Generating registration token for Azure Virtual Desktop Host Pool..." -ForegroundColor Cyan
209
210# Define Host Pool name and resource group (update these variables as needed)
211$hostPoolName = "vdpool-avd-prod-weu"
212$resourceGroupName = "rg-avd-prod-weu"
213$date = (Get-Date).AddHours(2).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK")
214
215try {
216 $registrationToken = az desktopvirtualization hostpool update `
217 --name $hostPoolName `
218 --resource-group $resourceGroupName `
219 --registration-info expiration-time=$date registration-token-operation="Update"
220
221 if ($LASTEXITCODE -eq 0 -and $registrationToken) {
222 Write-Host "Registration token generated successfully:" -ForegroundColor Green
223 Write-Host $registrationToken -ForegroundColor Cyan
224 } else {
225 Write-Host "Failed to generate registration token. Error: $registrationToken" -ForegroundColor Red
226 exit 1
227 }
228} catch {
229 Write-Host "Exception while generating registration token: $($_.Exception.Message)" -ForegroundColor Red
230 exit 1
231}
232
233<# Deploy Resources #>
234if ($deploy) {
235 Write-Host "Running a Bicep deployment with ID: '$deploymentID' for Environment: '$environmentType' with a 'WhatIf' check." -ForegroundColor Green
236
237 try {
238 az deployment sub create `
239 --name $deploymentID `
240 --location $location `
241 --template-file ./deploy-sessionhost.bicep `
242 --parameters ./deploy-sessionhosts.bicepparam `
243 --parameters updatedBy="$updatedBy" location="$location" locationShortCode="$locationShortCode" productType="$productType" environmentType="$environmentType" `
244 --confirm-with-what-if
245
246 if ($LASTEXITCODE -eq 0) {
247 Write-Host "Deployment completed successfully!" -ForegroundColor Green
248 } else {
249 Write-Host "Deployment failed. Please check the error messages above." -ForegroundColor Red
250 exit 1
251 }
252 } catch {
253 Write-Host "Deployment failed with exception: $($_.Exception.Message)" -ForegroundColor Red
254 exit 1
255 }
256} else {
257 Write-Host "Deployment not requested. Use -deploy switch to execute the deployment." -ForegroundColor Yellow
258}
259
260Write-Host "Script execution completed." -ForegroundColor Green
In the snippet below you can see the information that needs to be set manually in the ps1 file when you want to deploy your sessionhosts.
Use your own values in the deployment script else the registration key will not work
1$hostPoolName = "vdpool-avd-prod-weu"
2$resourceGroupName = "rg-avd-prod-weu"
3$date = (Get-Date).AddHours(2).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK")
How to run this?
You can find these files in my repository, but of course, you can also just copy and paste them from this website. One tip: keep all the files in the same folder.
Then, open your command prompt and navigate to the location where you saved the files. When you run the command below (with your own details, of course), the script will start executing.
The full command including product type and other parameters is mandatory for now because it’s part of the validation in the PowerShell command. However, for the session host Bicep itself, it is'nt really needed, since the values are already taken from the Bicep parameter file. You will see the warning message when deploying the script.
Just make sure to run the command exactly like this:
.\deploy-sessionhost.ps1 -subscriptionID "yoursubscriptionid" -location "westeurope" -productType "avd" -environmentType "prod" -deploy
When you don't want to use al those validators as shown below, just remove them in the validation set in the powershell script.
-subscriptionID "" -location "westeurope" -productType "avd" -environmentType "prod"
Some deployment details:
We will start by running the script using the command from the folder where the three files are located:
After the check it will ask you if you want to continu:
When confirming it will start the deployment you can check this under your deployments in the subscription.
And you can check the Hostpool if the registration key is being registered by the deployment script:
In my example i have deployed 2 Azure Virtual Desktops so it will take a couple of minutes when the deployment finishes, but you will see the registration in the hostpool as shown below:
So the Session Host are deployed!!
Conclusion:
Deploying Azure Virtual Desktop session hosts with Bicep really makes life easier. By using Azure Verified Modules and keeping most of the values in your Bicep parameter file, you can automate almost the entire process without touching custom scripts. The only thing you need is a simple deployment script to kick things off, and after that, Bicep does the rest.
When calling existing resources with Bicep you can easily build/update new resources for Azure Virtual Desktop and the best part is that it’s flexible and maintainable.
Thanks for reading and visiting my blog if you have any question reach out!