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
https://github.com/przybylskirobert/WVD

Ready ? So let’s buckle up.

Prerequisites

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

[Update]

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'
Connect-AzureAD
$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

4 Comments

  1. hi , thanks for this article – very useful
    Question – why in your example you do not use powershell to make Application Group Assignments.
    I am having issue doing so in my environment
    $wvdadgroup = get-azureadgroup -SearchString arg-dev-aue-wvdhp01-1-user
    $ResourceGroupName = Get-AzResourceGroup -name “p1-wvd-hp6-rg-1”
    $appgroupname = Get-AzWvdApplicationGroup -ResourceGroupName $ResourceGroupName -Name wvdhp06-DAG

    New-AzRoleAssignment -ObjectId $wvdadgroup.objectid -RoleDefinitionName “Desktop Virtualization User” -ResourceName $appgroupname -ResourceGroupName $ResourceName -ResourceType ‘Microsoft.DesktopVirtualization/applicationGroups’

    Getting this: Get-AzWvdApplicationGroup : Resource group ‘Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResourceGroup’ could not be found.
    At line:1 char:1
    + $appgroupname = Get-AzWvdApplicationGroup -ResourceGroupName $Resourc …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: ({ SubscriptionI…= wvdhp06-DAG }:f__AnonymousType2`3) [Get-AzWvdApplicationGroup_Get], RestException`1
    + FullyQualifiedErrorId : ResourceGroupNotFound,Microsoft.Azure.PowerShell.Cmdlets.DesktopVirtualization.Cmdlets.GetAzWvdApplicationGroup_Get

    • Robert P Reply

      Maxim,

      I have checked the code that you have provided and I can see some issues.
      1. When you assign something to the variable it is good to check what object type it has:

      $ResourceGroup
      $ResourceGroup = Get-AzResourceGroup -name “p1-wvd-hp6-rg-1”
      $ResourceGroup.GetType()
      IsPublic IsSerial Name BaseType
      ——– ——– —- ——–
      True False PSResourceGroup System.Object

      This line will give you the value that you are looking for.
      $ResourceGroup.ResourceGroupName

      $AppGroup
      $AppGroup = Get-AzWvdApplicationGroup -ResourceGroupName $ResourceGroupName -Name wvdhp06-DAG
      $AppGroup.gettype()
      IsPublic IsSerial Name BaseType
      ——– ——– —- ——–
      True False ApplicationGroup System.Object

      This line will give you the value that you are looking for.
      $AppGroup.Name

      2. Then when we go to the last line which is:

      New-AzRoleAssignment -ObjectId $wvdadgroup.objectid -RoleDefinitionName “Desktop Virtualization User” -ResourceName $appgroupname -ResourceGroupName $ResourceName -ResourceType ‘Microsoft.DesktopVirtualization/applicationGroups’

      It should be changed into this:

      New-AzRoleAssignment -ObjectId $wvdadgroup.objectid -RoleDefinitionName “Desktop Virtualization User” -ResourceName $AppGroup.Name -ResourceGroupName $ResourceGroup.ResourceGroupName -ResourceType ‘Microsoft.DesktopVirtualization/applicationGroups’

      Answering your question regarding the PowerShell usage for Application Group Assignments.
      My idea is to show to the readers that we can use both places (PowerShell, Portal) for the deployment 🙂

  2. Hi , is there any way to get the users assigned to application group via powershell command

    • Robert Przybylski Reply

      Hi Akshanta,
      Please read [Update] section in the article. There is a powershell solution for that.

Write A Comment