WVD with Azure Dedicated Hosts

Windows Virtual Desktop (WVD) let WVD is great technology that lets you publish desktops and apps securely from economical and scalable Azure all around the world.

To meet more rigorous compliance requirements some deployments require compute isolation – the resources need to run on hardware dedicated to just that customer. Azure Dedicated Hosts provides just this capability, enabling customers to have their own hosts with only their VMs on them: Azure Dedicated Host | Microsoft Azure.

Customers who need dedicated hosts are often large organizations (banks, governments, stuff like that) that invest in automation, and deploy using templates or Azure Blueprints, but not every can do that – templates can be intimidating, and the portal is friendlier.

If you do need to use dedicated hosts, one cool capability of dedicated hosts is that existing, compatible VMs can be moved to them after the fact (if you have them setup properly).

The struggle for some customers wanting to use dedicated hosts for WVD was related to the defaults used in the Azure Portal – VMs in a host pool were by default created in Availability Sets, which blocked them from moving to dedicated hosts. A recent portal change for WVD pool provisioning lets you select the availability options for your pool – including Availability Zones (data centers within an Azure Region):

Now you can create VMs outside of an Availability Set (setting instead an Availability zone), and then move the VMs right to your dedicated host!

Creating your WVD VMs

Go ahead and create a host pool like you always would – maybe with some “D Series” VMs – maybe us some D8s V3 or similar – but change the availability option on the pool to Availability Zone and set the zone (remember this setting – you’ll need it later!).

Creating Your Dedicated Host(s)

Creating a dedicated host is simple in the portal, just search for Dedicated Host in the portal, and set your options:

Be sure to pick a host family size that’ compatible with the VMs you want in your WVD Host Pool!
Not all VMs can move to all hosts… so check the compatibility here: Pricing – Dedicated Host Virtual Machines | Microsoft Azure

I should mention that you’ll also have to create a “Host Group” – you can do that first or whilst requesting your host (I had that circled in red above).

The IMPORTANT OPTION is the select the same Availability Zone (data center) for your host group as the VMs in your WVD pool!

Once you’ve got your host and your compatible VMs provisioned, it’s just a matter of move the VMs to the host, and I wrote a little PowerShell to help with that!

Powershell to Move VMs to the Host

All process is pretty simple:

  1. Get your dedicated host information
  2. Get your WVD Pool session hosts and loop
    1. Shutdown the Session VM
    2. Move the VM to the dedicated host
    3. Start the Session VM

Be sure and have all the right “AZ” modules loaded, in particular Az.DesktopVirtualization, and you should be all set – just put in some of those standard Azure “things” like the subscription ID / Resource Group / location….

#################################
# Azure Settings & other parms
#################################
$ResourceGroup 		= "DEDICATED"
$SubscriptionID		= "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$HostPoolName		= "Dedicated"
$Location		= "West US 2"
$HostGroupName 		= "hostgroup"
$HostName		= "host"

#################################
#Step 0 - Install WVD Module... in case you don't have it
#################################
# Install-Module -Name Az.DesktopVirtualization

#################################
#Step 1 - Connect to Azure Commercial and get started
#         note that for Azure Gov the command line would be different:
#         Connect-AzAccount -EnvironmentName AzureUSGovernment 
#################################
Connect-AzAccount 
Select-AzSubscription -SubscriptionId $SubscriptionID

#################################
#Move VMs to New Hosts
#################################
$myDH = Get-AzHost -HostGroupName $HostGroupName -ResourceGroupName $ResourceGroup -Name $HostName

$VMs = Get-AZWVDSessionHost -ResourceGroupName $ResourceGroup -HostPoolName $HostPoolName 
Foreach ($VM in $VMs) { 
	$DNSname = $VM.name.split("/")[1]
	$VMname = $DNSname.split(".")[0]
	$myVM = Get-AzVM -ResourceGroupName $ResourceGroup -Name $VMname
	$myVM.Host = New-Object Microsoft.Azure.Management.Compute.Models.SubResource
	$myVM.Host.Id = $myDH.Id
	Stop-AzVM -ResourceGroupName $ResourceGroup -Name $VMname -Force
	Update-AzVM -ResourceGroupName $ResourceGroup -VM $myVM 
	Start-AzVM -ResourceGroupName $ResourceGroup -Name $VMName
}