Windows Virtual Desktop – Group Sync script

In my previous post, you read about how to setup a full WVD environment. As you may have noticed, providing permissions to the applications or desktops can only be done using PowerShell (at the time of writing this article).

This was a bit odd for me, as many enterprises use AD / AAD groups to provide permissions to a group of users. So, behold – a new synchronization script for adding/removing users from WVD Application Groups based on the membership of AAD groups (which should be synchronized from AD).

The script

The script has 3 modes in can operate in, so let’s go over the manual version first:

Login to AzureAD & Login to RDS
(Connect-AzureAD & Add-RDSAccount -DeploymentURL

.\WVDSync.ps1 -AADGroup <AADGroupToSync>
-HostPoolName <Pool> -AppGroupName AppGroup1 -TenantName <TenantName>

(optionally -Login $true can be added if you are not logged in yet)

The script will read the users (UPN) from the AAD Group and read the users that currently have permissions on the AppGroup in the specified hostpool/tenant. If users are missing, they will be added to the AppGroup, if users need to be removed, they will be removed from the AppGroup.

It’s that simple.

Automated Sync

But if you have a more complex setup, you would need to be running this script for every appgroup/hostpool/tenant that you have. Which is why the script also has a fully automated function. For this, the description of every AppGroup in WVD needs to have the AAD group as it’s value. You can either specify this during the AppGroup creation, or using the set-AppGroup command:

Set-RdsAppGroup -TenantName <TenantName> -HostPoolName
<PoolName> -Description "AppGroup1Users"

To ease the implementation of this, the automated version runs by a service principle login. To use the fully automated version you first need to provision the script:

Login to AzureAD & Login to RDS
(Connect-AzureAD & Add-RDSAccount -DeploymentURL

-Provision $true   

The provisioning works similar to the B2BSync script. A local certificate is created and granted permissions for your current user account to read it, an AAD ServicePrinciple is created and then assigned permissions. A scheduled task is also created (disabled for now in the script). The output of the provision is an ApplicationID. Take note of this ID.

Running the fully automated script is easy, it requires the ApplicationID as input and it will run fully automated from there:

                Open a PowerShell (no admin required)

.\WVDSync.ps1 -Automated $true
-ApplicationId 'cde31d2f-4495-420a-ac50-blablabla'

The script will go through all your tenants, all hostgroups in all tenants and all AppGroups in all hostgroups. It will read the description field of the appGroup, try to find a matching AAD Group and if found will synchronize the UPN’s.

As the Desktop Application Group is the same for every hostpool, we cannot set the Description by default. That is why the script on line 83 has:


Desktop Application Group

To assign permissions to the individual hostpools, create a group in AD that matches hostpool-WVDDestopUsers or change the value in line 83 to what you prefer. As long as it starts with the hostpoolname, you should be good (example: UAE-North-Pool1-WVDDesktopUsers)


As we are adding/removing UPN’s to groups, and therefore assigning permissions, a logfile is created everytime the script is run (in every mode). The logfile will be stored in the same location as the script.

Tagged , ,