WVD Admin - A native administration Gui for Windows Virtual Desktop
Windows Virtual Desktop is generally available under continuous improvement and currently available in the ARM (Spring) and in the Classic (Fall) version. The ARM version is completely into the Azure Portal. Sometimes it helps to have a native GUI to make some configuration and - for me, most important - to have an easy image handling to deploy session hosts based on a template VM (golden image approach). Therefore I build a native Windows application to do this, and I’m happy to share it with the community.
The current version supports a lot of configuration and administration capabilities, and I’m continuously improving WVDAdmin. Some features:
- Add, edit and delete host pools
- Add, edit and delete application groups
- Add, edit and delete application and desktop (you can add a new app with the Windows file-open-dialog)
- Add a list of users to applications or a desktop (separated by ;)
- Send messages to a single user and users on a specific session host
- Logoff single users or all users of a specific session host
- Start and deallocate session hosts (the Azure VM behind)
- Delete session hosts and the VMs in Azure, including disks and nics
- Run commands and scripts on multiple session hosts (trigger Windows updates, enable RDP Shortpath, …)
- Create an image from a template VM without destroying the template VM (golden image approach)
- Rollout several new session hosts based on a template image - including domain join and WVD installation and registration (comparable to Citrix MCS)
- Rollout VM Scale Sets
- Start and deallocate Scale Set instances
- Re-image Scale Set instances
- Add or remove Scale Set instances
- and some more things
I'm continuously updating WVDAdmin to make it easier to administrate and deploy WVD, users, and session hosts. Click to see the change history.
|Release||Changes & Notes|
|184.108.40.206||Add: Experimental feature: Add applications to session hosts from Windows Package Manager repository|
|220.127.116.11||Change: Having a script-path for building images is no longer needed. If you leave the text box empty, the local script coming with WVDAdmin will be used and directly send to the VM|
|18.104.22.168||Add: On a session host > State > Mouse over will show the health report of the host|
|22.214.171.124||Fix: The drop-down list “Feature release” was not shown correctly. Feature release is the selector between the different WVD versions like Fall (WVD classic) and Spring (WVD modern on ARM)|
|126.96.36.199||Add: You can run scripts on multiple classic session hosts: Win Updates: Install new available updates; Custom script: Custom script located in the program files folder of WVDAdmin|
|188.8.131.52||Add: Sorting order for WVD resources|
|184.108.40.206||Add: Support for Eav4 and Easv4-series|
|220.127.116.11||Add: Speed up adding a lot of VMs to the treeview|
|18.104.22.168||Add: Support for using availability zones. Select it from the drop-down list right to the resource group list|
|22.214.171.124||Add: You can run scripts on multiple ARM session hosts: Win Updates: Install new available updates; Custom script: Custom script located in the program files folder of WVDAdmin|
|126.96.36.199||Add: Multi selection and action on session hosts for ARM if you select a session host container; Fix: Scale Set instances wasn’t shown in 1.6.23|
|188.8.131.52||Fix: New image was not visualized in the tree view after creation|
|184.108.40.206||Add: Support for shared image galleries: Add a shared image gallery from the Azure Portal into a resource group managed by WVDAdmin. In WVDAdmin right-click an existing image and select “copy to shared image gallery”. An image can be rolled-out right clicking the shared image|
|220.127.116.11||Add: Double-click on the tag Logs, Sessions or Sessions V2 enlarge the part of the windows (double-click again to revert)|
|18.104.22.168||Fix: API change from Microsoft cause that updating a host pool property fails if the location is written like “Central US” (centralus is no problem); Add: First version able to deploy session hosts from images in a image gallery|
|22.214.171.124||Add: Session hosts icons are now based on the availability state; Fix: Enumerating thousands of sessions with thousands of session hosts takes longer as expected (> 4 minutes)|
|126.96.36.199||Add: Support US Government Cloud. Activate: Add a new string Reg_SZ “Environment” with value “US” to HKCU\SOFTWARE\ITProCloud\WVDAdmin”|
|188.8.131.52||Add: Support for VM types: Dv4 and Dsv4-series, Ev4 and Esv4-series|
|184.108.40.206||Fix: WVD ARM resources are deployed with the tags; Workspaces and host pools are separated by subscription name|
|1.6.9.00||Fix: Generating toke for Spring host pool fails sometimes (Error: ExpirationTime value must be between one hour and 30 days from now” - An error occurred while gathering an WVD2 token from backend: Object reference not set to an instance of an object.)|
|1.6.5.00||Add: Support for DD_v2 and DDS_V4 virtual machine types; Fix: Forwarding from the WVD API cause a authentication lost (error 401, 403 reading resources in the FALL update)|
|1.6.4.00||Add: Support for GEN2 virtual machines|
|1.6.2.00||Add: New naming feature for new session host. Default (is): Name for a session host is the highest matching name +1; new concept (must be enabled): Name for a session host is the next free name. To enable add a reg dword to HKCU\Software\ITProCloud\WVDAdmin Name:NamingMode and value to “1”|
|1.6.1.00||Fix: Default session limit for V2 host pool is now 999999|
|1.6.0.00||Change: The tag WVD.Path is aligned to Microsoft naming of “tenant” and “host pool” for the spring update. Tenant=resource group name and no longer subscription name|
|1.5.9.00||Add: Load assigned users button to the app group tab (fall update)|
|1.5.7.00||Add: You can join existing VM’ to a host pool (VMs must be domain joined and not in a host pool right now)|
|1.5.6.00||Add: You can now move session host around host pools not created with WVDAdmin (it downloads the necessary files automatically); you can join existing VM’ to a host pool (VMs must be domain joined)|
|1.5.5.00||Fix: Enumerating VMs was endless in some circumstance|
|1.5.4.00||Add: Migration from Fall to Spring Update; moving session hosts to another host pool|
|1.5.3.00||Fix: Improvement updating the treeview|
|1.5.0.00||Add: Supporting the WVD Spring Release / Spring Update ; Some user operations from the session grid are now async; Fix: Spontaneous resize of the windows if data are reloaded|
|1.4.9.00||Add: Filter users, session hosts and host pools in the overview of sessions|
|1.4.8.00||Add: Support to add users by groups from Azure Active Directory, including an AAD browser (check my blog post and configure the service principal to use this feature)|
|1.4.6.00||Add: New VM sizes; all new scale sets are deployed as really scalable version (up to 600 instances each)|
|1.4.4.00||Fix: Service Principal Keys with some special characters are working now; Add: Faster loading of resources from WVD and Azure backend|
|1.4.2.00||Add: Support for NVv4 VM sizes (based on AMD Radeon Instinct MI25-GPU); support to set custom Azure tags for resources while deploying resources|
|1.4.0.00||Fix: From an older version, disks are deployed as standard-hdd even if premium-disk was selected; Change: Connection views are now located parallel to the logging list on the bottom (tenant-view); Add: Function to check for an updated version via https://blog.itprocloud.de/assets/files/WVDAdmin.xml|
|1.3.6.00||Add: New tag for session hosts: WVD.Path - used by Azure Monitor for WVD and Azure Autoscale for WVD - aka Project MySmartScale if an installed language pack conflicts with the Microsoft RDAgent (read this post to learn more)|
|1.3.5.00||Add: Allow an local admin to shadow a user session (WVDAdmin needs direct access to the session host via RDP)|
|1.3.4.00||Add: Networks are now listed as VNET/SUBNET in the rollout tab|
|1.3.3.00||Add: Support for a special mode if your WVD tenant and the session hosts in two different Azure Active Directory tenants|
|1.3.1.00||Fix: WVDAdmin crashed if 1.3.0 is your first version of WVDAdmin (HKEY_CURRENT_USER\Software\ITProCloud doesn’t exist while checking for multi-tenancy mode)|
|1.3.0.00||Add: AAD multi-tenancy mode (drop down list to handle different AADs) - https://blog.itprocloud.de/Windows-Virtual-Desktop-Windows-Virtual-Desktop-Administration-for-CSP-and-Consulting-Partners|
|1.2.8.00||Add: If you click a tenant a tenant wide list of sessions is listed. Logoff or send messages to multiple sessions|
|1.2.7.00||Add: The main window of the application is now resizeable|
|1.2.5.00||Add: Support for Scale Sets (with normal and ephemeral disks) -> see below|
|1.2.4.00||Add: Support for availability sets|
|1.2.3.00||Add: Support for automatic and static assigned host pools|
|1.2.1.00||Fix: Logging of rollout parameter by Azure custom extension is removed to avoid logging secrets|
|220.127.116.11||Fix: Rollout - OU can now be empty to join the default OU|
|18.104.22.168||Add: Supporting “special license mode” to save up to 50% on compute-cost (https://docs.microsoft.com/en-us/azure/virtual-desktop/apply-windows-license)|
|22.214.171.124||Add: Template VM can now be a VM with a standard disk (non-managed)|
|126.96.36.199||Fix: If you delete a VM the OS disk will deleted as well|
|188.8.131.52||Support for ephemeral disks|
|184.108.40.206||First published version - without auto-update of WVD Admin|
To work with the GUI, you need a service principal (function account) with permission to administrate access to the WVD and Azure resources. I decide to use a service principal to avoid confusion if my Azure AD user is only a guest account in the WVD tenant I have to administrate and easily switch between different tenants.
To create a service principal, go to your Azure AD -> App registration -> New registration and type a name for your principal like “ svc_WVDAdmin” and press “register”.
Click on “certificates & secrets”. Click “new client secret”, select a validity period and a description (like “Key01”). Press “add”.
Copy the generated key directly - it will never be displayed again. Note the key for later.
To assign users to app groups, the service principal needs two API permissions to get the users and groups from Azure AD:
API Permissions: Add the permission “Azure Active Directory Graph” -> Application Permission -> Directory.Read.All
Add the permission “Microsoft Graph” -> Application Permission -> Directory.Read.All
To consent, the permission and administrator of Azure AD have to grant this:
Go to “Overview”. Note the “Application (client) ID” and the “Directory (tenant) ID” as well.
You now have all data for your service principal:
- Tenant id
- Service principal id (application id)
- Service principal key
This chapter is for WVD Classic / Fall. Skip this chapter if you only work with WVD ARM (Spring).
To use WVDAdmin you need at least an existing WVD tenant. If you new to WVD follow this article to create a WVD tenant: https://docs.microsoft.com/en-us/azure/virtual-desktop/tenant-setup-azure-active-directory
You have to use PowerShell to give the WVD the appropriated permission:
Import-Module -Name Microsoft.RDInfra.RDPowerShell # log on with an administrative user account to your Add-RdsAccount -DeploymentUrl "https://rdbroker.wvd.microsoft.com" # list rds tenants Get-RdsTenant # give your service principal the right permission New-RdsRoleAssignment -TenantName "Builder City" -RoleDefinitionName "RDS Owner" -ApplicationId 89050a12-xxxx-xxxx-xxxx-000000000000
This chapter is for WVD ARM / Spring. Skip this chapter if you only work with WVD Classic (Fall).
The service principal needs permission to add and modify WVD resource objects (host pools, workspaces, app groups). To assign users and groups to app groups, the service principal needs the owner role on the resource groups you want to use for your WVD environment. Add the service principal in the next step and use the owner role.
This chapter is for WVD ARM / Spring. Skip this chapter if you only work with WVD Classic (Fall).
If you have never worked with WVD, you have to register the WVD resource provider once. To do that, go to the Azure portal -> subscriptions -> select your subscription -> Resource providers
Search for “Microsoft.DesktopVirtualization” and click on “Register”.
The service principal needs permission to subscriptions or resource groups to manage your WVD resources, imaging template VM and rollout session hosts.
Open the Azure portal and go to the resource groups you want to use or to the subscriptions. In each resource group/subscription, click “Access control (IAM)” -> select “Add” -> Add role assignment. Select “owner” and search in “Select” for your service principal name. Click on the principal and save the settings.
Note: Owner is needed to assign users to app groups. For other resources, “contributor” is fine.
The service principal must have permissions to your virtual network (vnet) to assign new VMs to the right subnet. Go to your vnet, click “Access control (IAM)” -> select “Add” -> Add role assignment. Select “contributor” and search in “select” for your service principal name. Click the principal and save the settings. You could skip this step if you assigned the service principal to the subscription or to the resource group containing your vnet.
Today each session host must be part of a “native” active directory domain (or have to use the domain services). To add new session hosts unattended, we need an administrative user account to add a computer object to the active directory domain. You can use an existing one, or you can create a new service user:
Open “Active Directory Users and Computers” and create a user object with a complex password, and set a password to “never expire” (if you fine with this). I added the user srv_WVD-Join@itprocloud.de.
Delegate permission for the user to an OU. I found a really good blog post from Prajwal Desai. Check out hist post on (external web site): Method 2 – Delegate rights to user/group using Active Directory Users and Computers
In my case I added my function account to: “OU=WVD,OU=Azure,OU=Site,OU=Servers,OU=Sys,OU=Organisation,DC=ITProCloud,DC=test”
In earlier versions (<1.6.40), you had to provide the deployment script and the WVD agent binaries on a custom file share or blob storage. With WVDAdmin 1.6.40 or newer, this no longer mandatory. In some cases, where virtual machines don’t have access to the internet to download the WVD agent binaries, you can use a custom file share.
Hint: Alternatively, you can use Azure blob storage to store the script. Make the blob storage read-only and use the URL as rollout script-path. E.g.: https://sharedservices01.blob.core.windows.net/wvd
Create a file share for the configuration script (which adds new session hosts to the domain and install the WVD agent). Give everyone at least read permissions. Set the NTFS permissions to everyone and read. This is necessary while during the first startup, the VM extension tries to execute the script. In this process, the file share is accessed anonymously.
Place the following files in this share:
- ITPC-WVD-Image-Processing.ps1 (rename the download to .ps1)
- Microsoft.RDInfra.RDAgent.msi (rename the file)
- Microsoft.RDInfra.RDAgentBootLoader.msi (rename the file)
Make sure that you rename the files to fit the list above (without version numbers).
Important: If you are using Windows Server 2019 as file share, make sure that anonymous file share access is enabled. Create a GPO for the session hosts containing the following configurations:
- Security Options:
- Accounts: Guest Account Status: Enabled
- Network access: Let Everyone permissions apply to anonymous users: Enabled
- Network access: Do not allow anonymous enumeration of SAM accounts and shares: Disabled
Please start WVDAdmin. Before you load WVD and Azure data, copy the Azure tenant id, service principal id, and service principal key into the welcome tab. Press save and load the data by clicking “Reload all”.
You are now able to administrate WVD, create images from template VMs and rollout new session hosts.
The first time you want to roll out new session hosts, you have to enter some information from your Active Directory and file share configuration from above:
Local Admin and local pw. are the local administrator account credentials which you can enter at this time.
You can rollout VMs and VM Scale Set with images created by WVDAdmin. These images contain the logic to join the AD domain and WVD.
You can simple create an image from a template VM. The template VM must part of your AD like a standard client. You have not to sysprep or to normalize this template VM. Use the same template VM for Windows and application updates.
Following these steps to build your template:
- Install a VM in the Azure portal. Select the right OS (like Windows 10 Enterprise for Virtual Desktops)
- Make all Windows updates
- Join the VM to your AD
- Install your application
- Make your customizing (like installing language packages)
- Shutdown the template VM
To create the image, open WVDAdmin and
- Navigate to the Azure template VM (Azure -> Virtual Machines -> RG -> VM)
- Right-click -> “Create a template image”
- Select the resource group to store the image
- Press “Capture”
You can and should reuse the template VM for new updates and applications. After these changes, shut down the template VM and create a new image.
First node: VM Scale Sets cannot autoscale WVD session hosts. Auto-scaling only works for stateless services like a web server. But if you need hundreds of session hosts, then VM Scale Set allows you to work with these numbers efficiently.
From version 1.2.5, WVDAdmin support VM Scale Sets. A Scale Set can have several instances, which are the VMs / session hosts. There are some essential things you have to know if you use VM Scale Set with WVDAdmin and WVD itself:
- Build a Scale Set with WVDAdmin. Select an image, right-click and select “Create session host from image”. Check “Rollout as VM Scale Set”
- You can use regular disks and ephemeral disks. If you use ephemeral disks, you cannot deallocate the instances of your Scale Set. You have to delete the instances
- Today, you can not use ultra disks
- You can add and remove instances with WVDAdmin or in the Azure Portal. New instances will join the domain and WVD
- A new instance can only join WVD if the session host with the new name doesn’t exist. If you delete instances, the session host entry will also be removed
- You can re-image single instances or all instances of a Scale Set. After that, the instances are “clean” as at the first rollout
- Adding instances or re-imaging assumes that the Scale Set configuration (which is a custom script extension) has a valid WVD token to join new instances to WVD. While WVD provides only one token per host pool and that the token can be expiring, you can update the token with a right-click on the Scale Set and select “Update WVD token”. The max. lifetime of a token is 59 days
- Unfortunately, WVDAdmin cannot change the source image for a VM Scale Set. So if you want to update the image for a host pool, take these steps:
- Rollout a new Scale Set based on the new image
- Disable new logons for the old session host from the previous Scale Set
- Test the host pool based on the new Scale Set
- If no user logged on to the ancient Scale Set, remove all instances from the Scale Set (this deletes the session hosts in WVD as well)
- Remove the Scale Set
Ephemeral disks are awesome. They give you a high performance free of charge. Especially in a WVD multiuser environment where no data a stored permanently on the session hosts, this kind of disk can give you some value add.
Ephemeral disks are running on the Azure hypervisor and not stored. This has some advantages:
- There are no storage costs (!)
- A very high data throughput because the disks exist on the hypervisor
- See @MichaWets blog post for more information: https://www.cloud-architect.be/2019/07/15/windows-virtual-desktop-running-on-ephemeral-os-disks/
- You can not deallocate a VM with this disk type - you have to delete the VM (and roll out a new one instead of starting a “normal” VM)
- Not each VM size is available, and there are limitations of the disk size (image size for rollout) based on the VM size: Max ephemeral disk size for Standard_D4s_v3 is 64 GByte while a Standard_D8s_v3 can have up to 128 GByte. See https://docs.microsoft.com/en-us/azure/virtual-machines/linux/sizes-general
- If the Azure hypervisor fails, your session host will fail as well and can not be re-deployed automatically
- The image is not created. An error message occurs:
- Check if your template VM part of the AD
- If your file server Windows Server 2019, read above
- Check if you have set the NTFS and share permission correctly
- Azure portal: Go to the temp VM (next to the template VM) and check the extension installation state. There should be an error message like script not found, access denied, etc.
- Have you renamed the RD agent and bootloader?
- Is the script saved correctly: ITPC-WVD-Image-Processing.ps1, not ITPC-WVD-Image-Processing.ps1.txt
- Don’t forget to delete the temp VM and temp disk to avoid costs
- Make sure that your template VM uses managed disk
- The script generates additional log files in %WinDir%\System32\LogFiles
- Windows 7: Make sure to install PowerShell 5.1 and all Windows updates (including the optional updates without the language packages) to the template VM and restart the VM to take effect: https://www.microsoft.com/en-us/download/details.aspx?id=54616 Makes sure that you use the newest script file from 09/2020: ITPC-WVD-Image-Processing.ps1
- NEW: An endless loop of “Waiting for the temporary vm (power off)” : Update to the newest PowerShell script for generalizing: ITPC-WVD-Image-Processing.ps1
- You have created a host pool, an app group, and assigned a user to the app group, but the user cannot see the apps/desktop.
- Windows Virtual Desktop administration with WVDAdmin
- Configure WVDAdmin
- Build an image
- Tipps & Tricks