Azure AD Joining an Azure Virtual Desktop Multi-user Image

Note – In this blog, all references to AVD are utilizing Windows 10 multi-session.

I’d like to preface this by saying the following is a workaround and is not officially supported by Microsoft, in saying that I am yet to stumble upon any negative implications of doing the below, hence I thought I’d do a writeup on it.

In a virtual desktop environment its common to build your workload from a common image, meaning application, configuration and updates are applied to the image that is then used by the workload to scale out VMs that users access.

This ensures that should users access a different VM their experience will be as identical as possible given the same applications and configuration is present between the two hosts.

Recently I’ve been taking a look at Azure Virtual Desktop making use of all the recent advances including Azure AD Join and enrollment in Microsoft Endpoint Manager (Intune), in addition we’ve been using Nerdio Manager for Enterprise to reduce the friction of setting up this environment, and automating it to scale based on usage.

Nerdio uses a different terminology for Images, calling them Desktop Images; although behind the scenes there is no difference between this and the native Azure toolset.

At the time of writing Microsoft allows you to perform an Azure AD join (AADJ) of Session Hosts within a Host Pool as well as enrollment in Endpoint Manager, this allows you to deploy applications, configuration and scripts.

Deploy Azure AD joined VMs in Azure Virtual Desktop – Azure | Microsoft Docs

Using Azure Virtual Desktop multi-session with Microsoft Intune | Microsoft Docs

However what isn’t currently documented as supported is the ability to join a Image (Desktop Image) to Azure AD and enroll in MEM, this post outlines a workaround that can be used to join an Image to Azure AD and MEM where it can then be targeted for application deployment and updates.

Firstly, we need to enable the System Identity option on the Virtual Machine, this provides a device credential that the Azure AD Join VM Extension will later use to join the domain.

Navigate to the Image VM in the Azure Console, under the Settings header select Identity and enable the System assigned identity.

Option to enable system assigned identity in Azure Console

Next, we can enable a VM Extension that performs the Azure AD join and enrollment with Microsoft Endpoint Manager, at this time this can only be done via the CLI, the following is a PowerShell script that can be imported as a Scripted Action in Nerdio or altered to be run in Cloudshell.

#description: Enables System Identity on VM and Adds AADLoginForWindows Extension

<# Notes:

This Scripted Action will enable System Identity on the targeted Virtual Machine and addition of VM Extension which will perform an AAD Join of the VM and subsequently an enrollment in Microsoft Endpoint Manager

To run this script, find the desktop image in Nerdio, and use the menu to the right of the host to 
select "Run script"

#>

$ErrorActionPreference = 'Stop'

$subscriptionID = $AzureSubscriptionId
$rgname = $AzureResourceGroupName
$vmname = $AzureVMName

#Log in to your subscription
Select-AzSubscription -Subscription $subscriptionID
Set-AzContext -Subscription $subscriptionID

# Enable System Identity
$VirtualMachine = Get-AzVM -ResourceGroupName $rgname -Name $vmname
Update-AzVM -ResourceGroupName $rgname -VM $VirtualMachine -IdentityType SystemAssigned | Out-Null


#Setup Variables for VM Extension
$AzVM = Get-AzVM -Name $AzureVMName -ResourceGroupName $AzureResourceGroupName
$Type = "AADLoginForWindows"
$PublisherName = "Microsoft.Azure.ActiveDirectory"

$ExtensionSettings = @'
{
     "mdmId": "0000000a-0000-0000-c000-000000000000"
}
'@

$ExtensionVersion = "1.0"

$VMExtension = @{
ResourceGroupName = $AzVM.ResourceGroupName
Location = $AzVM.Location
VMName = $AzureVMName
Name = $Type
Publisher = $PublisherName
ExtensionType = $Type
SettingString = $ExtensionSettings
TypeHandlerVersion = $ExtensionVersion
}

#Perform VM Extension addition
Set-AzVMExtension @VMExtension

To breakdown the above, this is a standard Azure AD Join VM Extension however it also includes a mdmId value which is a global GUID for Microsoft Intune, this instructs the VM to not only join the domain; but also enroll in MEM.

Great! we’ve now joined our AVD Image to Azure AD and enrolled it in Microsoft Endpoint Manager, what’s next?

From here you can create an Azure AD Group to us in Microsoft Endpoint Manager for the image.

I would only recommend using this method to allow for Microsoft Endpoint Manager to deploy Win32 applications to the Image, any configuration profiles should be targeted to the running Session Hosts rather than the Image.

Upon testing this, I stumbled upon the fact that a sysprep of the Image (which is handled automatically by Nerdio) does not clean up any references to the device being joined to Azure AD or enrolled in Microsoft Endpoint Manager, and in fact Microsoft warns of this:

Sysprep will not run correctly on a Windows 10 device that has been MDM enrolled – Intune | Microsoft Docs

To get around this, you’ll need to remove the image from Azure AD and de-enroll from MEM on each commit to the image, this will clear any certificates and references on the image that it was ever joined to an Azure AD domain and was enrolled in Intune, a failure to do this will mean that when you power on your Session Hosts based on this image it will state that the VM has already been Securely joined to the domain and will either appear as a duplicate of the image and/or interfere with the join status of the image.

In order to do this we will need to gracefully leave the domain using dsregcmd and remove the AADJ VM Extension, this script (also designed for a Nerdio Scripted Action) can be retrofit to be run to automate these steps.

#description: Run this on the VM itself to de-register it from Azure AD

Start-Process dsregcmd -ArgumentList "/leave"
#description: Removes the device from Azure AD and Intune for sysprep

<# Notes:

This Scripted Action will remove the VM Extension for AAD Join.

To run this script, find the desktop image in Nerdio, and use the menu to the right of the host to 
select "Run script"

#>

$ErrorActionPreference = 'Stop'

$subscriptionID = $AzureSubscriptionId
$rgname = $AzureResourceGroupName
$vmname = $AzureVMName

#Log in to your subscription
Select-AzSubscription -Subscription $subscriptionID
Set-AzContext -Subscription $subscriptionID

#Setup Variables for VM Extension removal
$ExtensionName = "AADLoginForWindows"

#Perform VM Extension removal
Remove-AzVMExtension -ResourceGroupName $AzureResourceGroupName -Name $ExtensionName -VMName $AzureVMName -Force

When building a Session Host from this image, select the option to perform an Azure AD Join and the device will re-join Azure AD under the new hostname and will leave the preinstalled applications intact, should you have the need to target the same Win32 application to install; it will make use of your detection script to identify whether its already installed in the base image and will skip installation if this is the case.

I hope this helps you make use of Azure AD in your Azure Virtual Desktop environment while still maintaining a common state between Session Hosts.