Hi there,

It’s been a while since my last article.
Today I’d like to take you into the ride with Windows Virtual Desktop (WVD) series.

As always, there are some scripts that I’ve made to speed up the deployment

Ready ? So let’s buckle up.


Required resources

For initial WVD deployment, we will need the following resources:

  • Source of authentication – in our case, it will be Azure AD Domain Services (lab.azureblog.pl)
  • Virtual Network – required for Azure AD DS, WVD

Rest of the resources will be deployed within this article.

WVD resources

Below are the steps that should be taken in order to deploy:

  • Workspace – space where application groups are linked. This is the first piece of a puzzle that you can see after login to WVD
  • Application Group – a place where you can assign users and configure applications
  • Host Pool – a pool of session hosts. Within the host pool, you can decide to use it as a Desktop or Remote App.
  • Session Host – virtual machine or vmss connected to the host pool.

Diagram below visualize the relation between those components.

WVD resources

WVD deployment

Before we start the actual deployment, we need to declare some variables related to the region, naming, etc.

import-module Az.DesktopVirtualization
$ResourceLocation = "NorthEurope"
$WVDLocation = "eastUS"
$ResourceGroupName = 'rg-WVD-AzureBlog'
$prefix = 'AzLab'
$desktopWorkspaceName = $prefix + "_WSPACE_DESKTOP"
$desktopHostPoolName = $prefix + "_HOST_POOL_DESKTOP"
$desktopAppGroupeName = $prefix + "_APP_GROUP_DESKTOP"
$remoteWorkspaceName = $prefix + "_WSPACE_REMOTE"
$remoteHostPoolName = $prefix + "_HOST_POOL_REMOTE"
$remoteAppGroupeName = $prefix + "_APP_GROUP_REMOTE"
$maxLimit = 2

Those variables will allow us to run the next portion of code that will create WVD config

$WVDConfig = @(
    $(New-Object PSObject -Property @{WorkspaceName = "$($prefix)_WSPACE_DESKTOP"; HostPoolName = "$($prefix)_HOST_POOL_DESKTOP";  AppGroupeName = "$($prefix)_APP_GROUP_DESKTOP"; PreferedAppGroupType = 'Desktop'; FriendlyName = "$($prefix)_DSK" }),
    $(New-Object PSObject -Property @{WorkspaceName = "$($prefix)_WSPACE_REMOTE"; HostPoolName = "$($prefix)_HOST_POOL_REMOTE"; AppGroupeName = "$($prefix)_APP_GROUP_REMOTE"; PreferedAppGroupType = 'RailApplications'; FriendlyName = "$($prefix)_RAP" })

Now lets create ResourceGroup that will contain all our resources

New-AzResourceGroup -Name $ResourceGroupName -Location $ResourceLocation -Force
Resource group deployment

The next part will be tricky, as we are going to deploy 1 workspace, 2 host pools, 2 application groups at once.

foreach ($entry in $WVDConfig) {
    $workspaceName = $entry.WorkspaceName
    $hostPoolName = $entry.HostPoolName
    $appGroupname = $entry.AppGroupeName
    $preferedAppGroupType = $entry.PreferedAppGroupType
    $friendlyName = $entry.FriendlyName

    if ($preferedAppGroupType -eq "Desktop") {
        $aplicationGroupType = "Desktop"
    else {
        $aplicationGroupType = "RemoteApp"

    $workspacetest = Get-AzWvdWorkspace -Name $workspaceName -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue
    if ($workspacetest.count -eq 0) {
        Write-Verbose "Creating new Workspace:'$workspaceName' in resourcegroup: '$ResourceGroupName', under location: '$WVDLocation'"
        New-AzWvdWorkspace -Name $workspaceName -ResourceGroupName $ResourceGroupName -Location $WVDLocation
    else {
        Write-Verbose "Workspace:'$workspaceName' already exist."
    $hostpooltest = Get-AzWvdHostPool -Name $hostPoolName -ResourceGroupName $ResourceGroupName  -ErrorAction SilentlyContinue
    if ($hostpooltest.count -eq 0) {
        Write-Verbose "Creating new HostPool :'$hostPoolName' in resourcegroup: '$ResourceGroupName', under location: '$WVDLocation'"
        New-AzWvdHostPool -Name $hostPoolName -ResourceGroupName $ResourceGroupName -Location $WVDLocation -HostPoolType Pooled -LoadBalancerType DepthFirst -PreferredAppGroupType $preferedAppGroupType -MaxSessionLimit $maxLimit
        New-AzWvdRegistrationInfo -ResourceGroupName $ResourceGroupName -HostPoolName $hostPoolName -ExpirationTime $((get-date).ToUniversalTime().AddDays(30).ToString('yyyy-MM-ddTHH:mm:ss.fffffffZ'))
    else {
        Write-Verbose "HostPool:'$hostPoolName' already exist."
    $applicationGroupTest = Get-AzWvdApplicationGroup -Name $appGroupname -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue
    if ($applicationGroupTest.count -eq 0) {
        Write-Verbose "Creating new ApplicationGroup:'$appGroupname' in resourcegroup: '$ResourceGroupName', under location: '$WVDLocation'"
        $hostPoolID = (Get-AzWvdHostPool -Name $hostPoolName -ResourceGroupName $ResourceGroupName).id
        New-AzWvdApplicationGroup -Name $appGroupname -ResourceGroupName $ResourceGroupName -Location $WVDLocation -FriendlyName $friendlyName -HostPoolArmPath $hostPoolID -ApplicationGroupType $aplicationGroupType
        $appGroupID = (Get-AzWvdApplicationGroup -Name $appGroupname -ResourceGroupName $ResourceGroupName).id
        Update-AzWvdWorkspace -Name $workspaceName -ResourceGroupName $ResourceGroupName -ApplicationGroupReference $appGroupID
    else {
        Write-Verbose "ApplicationGroup:'$appGroupname' already exist."

Example output

Workspace deployment
Host pool deployment
Application group deployment

The script will check if the workspace, host pool, or application group already exists or no.

And this is how it looks from Azure portal perspective

WVD resources

Now we are having all the required resources to have WVD up and running. The next step is to assign users and deploy a session host.

In order to assign users we need to open our Application group and then under the Manage section chose Assignments

Application Group Assignments

Then using Add button add proper group in our case it will be WVD_users

Groups assignment


We can use PowerShell to assign the specific groups to the Application groups. In order to do this please run the following code

$resourceGroupName  = 'rg-WVD-AzureBlog'
$appGroupName = 'AzureBlog_APP_Group_Desktop'
$wvd_UsersGroup = Get-AzureADGroup -SearchString 'WVD_Users'
Write-Verbose "Assigning group '$($wvd_UsersGroup.DisplayName)' to the Application Group '$appGroupName'"
New-AzRoleAssignment -ObjectId $wvd_UsersGroup.ObjectID -RoleDefinitionName "Desktop Virtualization User" -ResourceName $appGroupName -ResourceGroupName $resourceGroupName -ResourceType `Microsoft.DesktopVirtualization/applicationGroups'

Now we need to deploy session hosts. These are the vms that will host our sessions and provide a full desktop experience or remote applications.

The easiest way to achieve it is to go to the host pool and under the Manage section chose Session hosts

Host pool overview

Then using Add button add a new session host. You will be moved to Add virtual machines to a host pool screen

Fill necessary information and go to Virtual Machines tab

VM configuration

On the Virtual Machines screen provide the required values and click Review + create

VM configuration

After about 10 minutes you should have successfully added vm to the host pool.
And this is the moment when your WVD is working!!!

To access WVD you can use the following link https://rdweb.wvd.microsoft.com/arm/webclient

Sign in using your account (member of the WVD_users group)

After login you should see our workspace (AzureBlog_WSPACE_DESKTOP) and Session-Desktop connection, After clicking it you will be connected to the session host using WVD

WVD portal

So that is all for today.

See you in second part of a series WVD: Creating custom image

Comments are closed.