Create the Azure Virtual Desktop backplane with PowerShell

Hello everyone!

When companies want to have a demo of Azure Virtual Desktop, you want to have a tool that will speed up to process of creating a Proof of Concept. With this post I will show you how to create the AVD Backplane with just one script. Once you have the backplane, you can easily add session hosts to the AVD environment. This post will show you how to use PowerShell to create the AVD environment.


  • Azure subscription
  • Contributor or Owner role on the subscription (less rights are possible, but take more time to setup)
  • Powershell version 7.2.14 (newer versions have issues with this script)  Check this link to download this version: Releases · PowerShell/PowerShell (
  • Powershell modules: Az.DesktopVirtualization, Az.Network, AzureRM, Az

Quick overview of the script

This script contains multiple sections of parameters. It is possible to create one big parameter section for all parts. This is build with modules, so not every section may be needed for your setup of AVD. The script has the sections explained. I will use VSCode to run this script, but every PowerShell tool is possible. 

PowerShell script

This script has parameters that need to be changed to your needs. 

The tenant has an Id that can be found within Microsoft Entra ID in the tenant properties.

The subscription has its own Id and can be found in the Azure portal.

You need to have a group available to add in this script. 


# Import modules for this script
Import-Module Az.DesktopVirtualization
Import-Module Az.Network

# Connect to tenant with the right subscription
$parametersAz = @{
    Tenant = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    Subscription = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

Connect-AzAccount @parametersAz

# Create the resource group
$parametersRG = @{
    Name = 'M2C-RG-AVD-PL-PS01'
    Location = 'westeurope'

New-AzResourceGroup @parametersRG

# Create the networking resources for AVD (Remove the parameter DnsServer when you want to use the Azure Provided DNS)

$parametersvnet = @{
    Name = 'M2C-AVD-VNET01'
    ResourceGroupName = 'M2C-RG-AVD-PL-PS01'
    Location = 'westeurope'
    AddressPrefix = ''
    DnsServer = ''
$virtualNetwork = New-AzVirtualNetwork @parametersvnet

$parameterssubnet = @{
    Name = 'M2C-AVD-SUBNET01'
    VirtualNetwork = $virtualNetwork
    AddressPrefix = ''

Add-AzVirtualNetworkSubnetConfig @parameterssubnet

$virtualNetwork | Set-AzVirtualNetwork

# Create VNET Peering with domain network (optional step)

$vnet1 = Get-AzVirtualNetwork -ResourceGroupName 'M2C-RG-AVD-PL-PS01' -Name 'M2C-AVD-VNET01'
$vnet2 = Get-AzVirtualNetwork -ResourceGroupName 'M2C-RG-ADDS' -Name 'M2C-RG-ADDS-vnet'
Add-AzVirtualNetworkPeering -Name LinkToVNet2 -VirtualNetwork $vnet1 -RemoteVirtualNetworkId $vnet2.Id 
Add-AzVirtualNetworkPeering -Name LinkToVNet1 -VirtualNetwork $vnet2 -RemoteVirtualNetworkId $vnet1.Id

# Create the AVD Hostpool
$parametersAVDHP = @{
    Name = 'M2C-AVD-PL-PS01'
    ResourceGroupName = 'M2C-RG-AVD-PL-PS01'
    HostPoolType = 'Pooled'
    LoadBalancerType = 'BreadthFirst'
    PreferredAppGroupType = 'Desktop'
    MaxSessionLimit = '10'
    Location = 'westeurope'

New-AzWvdHostPool @parametersAVDHP

# Create the AVD Workspace
New-AzWvdWorkspace -Name M2C-AVD-WS-PS01 -ResourceGroupName M2C-RG-AVD-PL-PS01 -Location 'westeurope'

# Get the resource ID of the host pool (needed for the creation of the Application Group)
$hostPoolArmPath = (Get-AzWvdHostPool -Name M2C-AVD-PL-PS01 -ResourceGroupName M2C-RG-AVD-PL-PS01).Id

# Create the Application Group for AVD
$parametersAG = @{
    Name = 'M2C-AVD-DAG-PS01'
    ResourceGroupName = 'M2C-RG-AVD-PL-PS01'
    ApplicationGroupType = 'Desktop'
    HostPoolArmPath = $hostPoolArmPath
    Location = 'westeurope'

New-AzWvdApplicationGroup @parametersAG

# Get the resource ID of the application group you want to add to the workspace
$appGroupPath = (Get-AzWvdApplicationGroup -Name M2C-AVD-DAG-PS01 -ResourceGroupName M2C-RG-AVD-PL-PS01).Id

# Add the application group to the workspace
Update-AzWvdWorkspace -Name M2C-AVD-WS-PS01 -ResourceGroupName M2C-RG-AVD-PL-PS01 -ApplicationGroupReference $appGroupPath

# Get the object ID of the user group you want to assign to the application group
$userGroupId = (Get-AzADGroup -DisplayName "MGT-AVDAccess").Id

# Assign users to the application group
$parametersUAG = @{
    ObjectId = $userGroupId
    ResourceName = 'M2C-AVD-DAG-PS01'
    ResourceGroupName = 'M2C-RG-AVD-PL-PS01'
    RoleDefinitionName = 'Desktop Virtualization User'
    ResourceType = 'Microsoft.DesktopVirtualization/applicationGroups'

New-AzRoleAssignment @parametersUAG

# Create the registration key for the creation of session hosts on AVD (now set to 24 hours, but can be extended)

$parametersRK = @{
    HostPoolName = 'M2C-AVD-PL-PS01'
    ResourceGroupName = 'M2C-RG-AVD-PL-PS01'
    ExpirationTime = $((Get-Date).ToUniversalTime().AddHours(24).ToString('yyyy-MM-ddTHH:mm:ss.fffffffZ'))

New-AzWvdRegistrationInfo @parametersRK

$parametersRKI = @{
    HostPoolName = 'M2C-AVD-PL-PS01'
    ResourceGroupName = 'M2C-RG-AVD-PL-PS01'

(Get-AzWvdHostPoolRegistrationToken @parametersRKI).Token

Running the script

When you run the script, you will notice that it will create the resources very quickly. So this will save you time when creating the AVD Backplane.

So sit back and relax when the script does his magic!

Now you can see that all resources are available in the Azure portal. How cool is that!


Final Thoughts

Creating this post was a lot of fun, but working with PowerShell is not the most common method for the creation of AVD resources. Using Bicep or Terraform is by far the most used method to create AVD resources, but using this script will be a lot easier then setting up Bicep or Terraform templates. Next time I wil show you how to create Session Hosts with PowerShell . So stay tuned for next time! Feel free to comment and ask me anything about this post!


  • Mischa Sachse

    Mischa Sachse is one of the founders of the Cloud Experts Community. Would you like to join in the fun? Make sure to contact him via the mail button below or find out more about him on his personal website.

Leave a Reply

Your email address will not be published. Required fields are marked *