Windows Virtual Desktop goes GA

Windows Virtual Desktop is now General Available

Awesome news today: Windows Virtual Desktop is now General Available!


Last year at Ignite 2018, Microsoft announced Windows Virtual Desktop (shortened to WVD) as the new name for RDmi, which was still in Private Preview at that time.
You can read my announcement blog here:

The next milestone was the Public Preview of WVD, announced on March 21 2019 by Julia White & Brad Anderson (here:
This step made it possible for everybody to start testing WVD, give feedback & suggestions to the Product Team.

During the Public Preview, the WVD Service (containing the Broker, Web Access, Gateway & Diagnostics services) was running in the East US for all regions.
This could result in higher latency (Round Trip Time or RTT) if your workload was running in your closest region, as all traffic was flowing through the gateway in the East US.

But as we got closer to the GA launch, we noticed a drop in RTT during our sessions in our Validation Hostpools.
This could only mean 1 thing: the WVD service was running in West Europe!

General Available

As of today, Windows Virtual Desktop is General Available (GA) for everybody.
This means you can start running your Production Workload with the full support of Microsoft on the WVD Service.
(Important: Microsoft will not give you by default support on your own workload, only on the WVD Service)

And as suspected, the WVD services are running in all commercial Azure Regions as we have suspected with the drop in RTT.

What’s coming?

At the moment, the MetaData of all WVD activities is still transmitted to the US that the moment. This will change in the coming months.

Microsoft will also add more clusters and Gateways in all regions over the coming months.

But that’s not all. Microsoft also announced features that are coming up later. Check out the video (link below) from Microsoft Mechanics on YouTube to learn more

Current feature set

The Feature set of WVD today is very clear:

  • It subtracts the Broker, Web Access, Gateway & Diagnostics services from your Azure subscription, making it Multi Tenant in comparison to RDS
  • It enables Reverse Connect with only outbound connections from your deployment
  • It enables you to take advantage of Azure AD, with features like Conditional Access, Multi Factor Authentication (MFA), etc
  • More PaaS! Compared to a RDS 2019 deployment, Microsoft goes even further with PaaS enablement. The entire WVD Service is a Azure PaaS service for you to use!


Microsoft added some additional licenses, entitling you to use the WVD service for free.

OSRequired license
Windows 10 Enterprise multi-session
Windows 10 Enterprise
Microsoft 365 E3/E5
Microsoft 365 A3/A5/Student use benefits
Microsoft 365 F1
Microsoft 365 Business
Windows 10 Enterprise E3/E5
Windows 10 Education A3/A5
Windows 10 VDA per user
Windows 7 EnterpriseMicrosoft 365 E3/E5
Microsoft 365 A3/A5/Student use benefits
Microsoft 365 F1
Microsoft 365 Business
Windows 10 Enterprise E3/E5
Windows 10 Education A3/A5
Windows 10 VDA per user
Windows Server 2012 R2, 2016, 2019RDS Client Access License (CAL) with Software Assurance

Check the FAQ of this page for further and the latest updates:


Microsoft acquired FSLogix November last year to enhance the Office 365 virtualization experience, especially when running WVD!
Because now you have great technology available for your Profile Management.
With FSLogix enabling faster load times for user profiles in Outlook and OneDrive, Office 365 ProPlus will become even more performant in multi-user virtual environments.

And the best part: it’s also free for all WVD entitled users!

With the launch of WVD, Microsoft also did a update of FSLogix to version 1909. Check the details in the Links section at the end.

These are the Licensing requirements for FSLogix

  • Microsoft 365 E3/E5
  • Microsoft 365 A3/A5/Student use benefits
  • Microsoft 365 F1
  • Microsoft 365 Business
  • Windows 10 Enterprise E3/E5
  • Windows 10 Education A3/A5
  • Windows 10 VDA per user
  • Remote Desktop Services (RDS) Client Access Licence (CAL)
  • Remote Desktop Services (RDS) Subscriber Access Licence (SAL)

The license that pops out is the SAL license. This means you can use FSLogix for almost any RDS & WVD deployment, on Azure, On-Prem or other Clouds

Is everything included in WVD?

This is an important topic! There are 2 things you need to know:
(ok, there are more, but these are the most important ones)

  • In the licenses above, you only get the usage of the WVD service.
    It does NOT include your Azure usage from your SessionHosts, AD deployment (Azure VM with Windows AD Role and AD Connect or Azure Active Directory Domain Services), File server (or Azure File Share), etc!
  • With simply deploying WVD, you will not be ready. You need to do a lot more than just deploy and lean back.
    You will need to
    • Validate your AD & Fileserver setup
    • Maintain your Azure Tenant & Subscription
    • Setup a backup strategy
    • Think about your updates (Software, Windows, Office, etc)
    • Cost management
    • Much more

Microsoft relies on Partners for this.
The company I work at, ASPEX, is one of those partners.
We developed a solution for provisioning WVD in an easy way, using the Best Practices from Microsoft & Azure, and our years of experience as a Hosting Partner and working on WVD from the beginning!

Check it out here:

More Readings

In the coming days, I’ll be posting some more details on the GA, the things to come and much more.
Below, you can find some links to more readings about the Genaral Availability of Windows Virtual Desktop, but also the TechCommunity link for WVD!
I try to follow this Community and answer/help where possible.

Microsoft announcing blog post:

Microsoft Mechanics video:

Microsoft TechCommunity:

Microsoft Docs on Windows Virtual Desktop:

Microsoft Docs on FSLogix:
FSLogix Update :

Windows Virtual Desktop Powershell cmdlets updated

Windows Virtual Desktop Powershell cmdlets updated.

Just a small update: the Powershell cmdlets for Windows Virtual Desktop have been updated & published 3 days ago, on the 17th of September.

The latest version available now is version 1.0.1288.1.

You can update your cmdlets using the Update-Module cmdlet

Or you could install the modules side-by-side using the Install-Module cmdlet with the -Force parameter

More information can be found here:

Windows Virtual Desktop running on Ephemeral OS Disks

Windows Virtual Desktop running on Ephemeral OS Disks

Windows Virtual Desktop running on Ephemeral OS Disks


Last week, Microsoft has made Ephemeral OS Disks General Available in all Azure regions (see the blogpost)!

Some information about Ephemeral Disks (from the Microsoft Docs):

Ephemeral OS disks are created on the local virtual machine (VM) storage and not saved to the remote Azure Storage. Ephemeral OS disks work well for stateless workloads, where applications are tolerant of individual VM failures, but are more affected by VM deployment time or reimaging the individual VM instances. With Ephemeral OS disk, you get lower read/write latency to the OS disk and faster VM reimage.

The key features of ephemeral disks are:

  • They can be used with both Marketplace and custom images.
  • Ability to fast reset or reimage VMs and scale set instances to the original boot state.
  • Lower latency, similar to a temporary disk.
  • Ephemeral OS disks are free, you incur no storage cost for OS disk.
  • They are available in all Azure regions.

The big question is: Can we use this for Windows Virtual Desktop?

The answer is not that simple, but let’s have a look…

Can you run Windows Virtual Desktop on Ephemeral OS Disks?

The simple answer is YES, you can! But (there is always a but) … It really depends on the deployment of your software/environment.

As you can read in the blogpost, the OS Disk is not written to Azure Storage, which makes the OS Disk stateless.
If your application is writing data to the OS Disk, this could be an issue.

Nevertheless, if you use FSLogix for your profile management (which is highly recommended!), and you have a good Master Image with your software pre-installed, then you should be able to use Ephemeral OS Disks!

The things you have to consider:

  • You cannot stop your VM to save costs on Compute. (restart is supported)
    Cannot Stop VM
  • The VM size (cache size) determines the Ephemeral Disk size.
    For Example: a Standard_DS3_v2 gives you the option to create an OS disk up until 172GB due to the 172 Gib cache size
    Standard_D4s_v3 will be an OS Disk up to 100GB, which is not enough for a Win10 Enterprise for WVD from the Azure Marketplace!
  • Resizing the Ephemeral OS disk is not supported, only during VM creation.
  • Resizing your VM size means that the data on the OS disk is deleted and the OS is re-provisioned!

How to deploy WVD with Ephemeral OS Disk?

I did a little fork on the GitHub templates from Microsoft from the Github Repo, because of 2 reasons:

  • You need to change the osDisk property in the ARM template
    osDisk highlight in the ARM Template
  • I did not want to change the DSC configuration, only the linked template location.

You can find the changed base ARM Template here:

And the Linked Template here:

The template is not changed, except the URI to the linked template.

MainTemplate Changes 1

MainTemplate Changes 2



Only the Linked Template using Managed Disks and the Azure Marketplace Gallery is available.

If you want to use a Custom Image, or Unmanaged Disk, then you will need to modify the linked templates yourself from the GitHub page.


How fast is it?

I did some basic tests on it, but they speak for themselves 😃

  • Deploy VM
    • Premium SSD: average: 7min 30sec
    • Ephemeral disks: average: 3min 10sec
  • Join AD
    • Premium SSD: average: 2min 40sec
    • Ephemeral disks: average: 1min 40sec
    • Premium SSD: average: 10min
    • Ephemeral disks: average: 9min

And then a small stress test using ParkDale, again, no explanation needed 😉

  • Premium SSD:
    ParkDale SSD disk 1MB ParkDale SSD disk 64kb
  • Ephemeral Disk:
    ParkDale Ephermeral disk 1MB ParkDale Ephermeral disk 64kb



Basically, you can run Windows Virtual Desktop on Ephemeral OS Disks, but you will need to have a good Master Image available, or a good deployment aftercare script.

But if you do, you will have a very fast running Sessionhost, with no OS Disk costs!

ExportImportRdsDeployment module has been updated and it has Backup functionalities now


After releasing my Powershell Module ExportImportRdsDeployment here, which helps you to migrate your RDS deployment to a newer version, I got some great feedback from users.
So it was time to implement some feature requests and improve some things from the first version.
The ExportImportRdsDeployment module has been updated and it has Backup functionalities now…

Updating the Module

The module is again available in the Powershell Gallery, so you can easily install and use it on any Windows Server.
Make sure you download and use version 2.0.

To check your current version:

Check current version

If you already have version 1.0 or 1.1, I would suggest you uninstall these versions, and install the latest.
To do this, you simply execute this commands:

Install newest version

Now you can import the module again and start using the updated cmdlets

Import the module

The changes

Get-Help improvement

I improved the instructions and help you get when using the Get-Help cmdlet.
You get more information and updated examples for all 4 cmdlets in the module.


Get Help improvements

Optional removal of collections & servers from deployment

In the previous version, when you executed the Export-cmdlets, the collections & the servers were removed from the deployment.

In the new version, you can export the collections or export the servers using the Export-cmdlets, without the removal functionality.
This way,

  • You can test the export and validate the migration before performing the actual migration.
  • You can use the module to create daily backups of your deployment/collections and quickly restore in case of issues or wrong manipulations on your deployment.

This is how you do it:

The Export-cmdlets are in Export-Only mode by default.
So if you run the cmdlet as you did before, no removal will be performed at the end of the export.

You can specifically declare this too, to make sure no removal is executed, using the RemoveCollections & RemoveServers switch-parameters:

If you want to perform the migration, you must specify the -RemoveCollections or -RemoveServers parameter and confirm the export with removal.
With this safety feature, you cannot mistakenly remove anything.

Confirm export

Reboot Pending check when importing

When running the Import-RDDeploymentToConnectionBroker cmdlet, the module will check if there is a Reboot pending on the target machines (in the export XML file).
If there are reboots pending, you can let the cmdlet try to reboot the VMs, or do it manually.
You cannot continue with the import until the servers are rebooted.

Reboot pending overview

File access test for XML file

Before performing an export, the cmdlet will test if you have permissions and access to the XMLFile location you have specified (or to the default location).
If you do not have access, the cmdlet will stop the export.

Export before removing

When performing an export with -RemoveCollections or -RemoveServers parameter, the cmdlet will first perform the export to the XMLfile before removing the collection/deployment.
The writing to the XMLfile must succeed first before continuing.

[Microsoft.RemoteDesktopServices.Management.RDSessionCollectionType] on a Windows 2012 machine

On a Windows 2012 machine, the cmdlet will correctly check for the [Microsoft.RemoteDesktopServices.Management.RDSessionCollectionType] when exporting/importing.


With this update to the module, you should be able to migrate your entire deployment more easily than before, again on any platform (like Azure) and faster than performing an in-place upgrade.

If you have any questions or feature requests, do not hesitate to contact me using the comments, or via Twitter/LinkedIn.

MVP 2019-2020

Honored to receive my first Microsoft MVP Award

Honored to receive my first Microsoft MVP Award

Simply said: it has been really crazy the last 2 years…

I had the chance to speak at several conferences about Windows Virtual Desktop (WVD, previously Remote Desktop modern infrastructure or RDmi), I met so many fantastic MVPs at these conferences that I admire, I got to know many people inside Microsoft Product teams and work with them (just to name a few: Clark, Eva, Christian, David, Pavithra, Roop, Loay, Bart and many more). Absolutely crazy! But so amazing and so inspiring.

I started to use Twitter more and more, I started to write blogposts, I’m helping the MS Product teams, I’m creating scripts and modules for the community, and best part still has to come: I enjoy it more and more every day 😃

I was having a romantic Saturday with my wife (the kids were at my parents for a day 😉 ), we went shopping & enjoy each-others company for the day, and we would finish it with a great dinner in a local restaurant. And then it happened, near the end of the shopping day, I received an email with the best title you can hope for: Congratulations 2019-2020 Microsoft MVP!
MVP 2019-2020
Lets say that the dinner was an excellent moment to celebrate this and it made our day even better.

I want to thank all the people at the MS Product teams that I get to work with, all the MVPs (Freek, Eric, Tom, Maarten, …) who gave me great advice and showed me how they work, but also for the great talks, all the people I have met these last couple of years and helped me get to this point, but also ASPEX to give me opportunity to grow more into Azure, RDS and WVD : THANK YOU.

Last but not least, I want to thank my wife and kids. They supported me throughout these last years, even when it was really busy for us😘!

I’m very honored to receive this MVP Award, to be part of this amazing group of people and to continue to work with all of you.



Add Sessionhosts to your existing RDS deployment using ARM templates and Invoke-AzureRmVMRunCommand

Add Sessionhosts to your existing RDS deployment using ARM templates and Invoke-AzureRmVMRunCommand


If you are using ARM-templates & Desired State Configuration (DSC) for your RDS deployments, you will be able to cover almost all your needs.
But you could also use different options or technologies for your needs.

A great example is the combination of an ARM template with the CustomScriptExtension (for installing the RDS Sessionhost role on the VMs), the JsonADDomainExtension (to join the VM to a domain) and the new Invoke-AzureRmVMRunCommand cmdlet.

In this blog, I will show you how you can use ARM templates & the new Invoke-AzureRmVMRunCommand cmdlet to add new sessionhosts to your already existing RDS deployment, and more!

The Invoke-AzureRmVMRunCommand cmdlet

The new cmdlet allows you, as an admin of the Azure subscription, to “Invoke a run command on the VM“.
Run Command uses the VM agent to run PowerShell scripts within an Azure Windows VM. This means that the script will be executed as the Local System account (important to remember).
There are some restrictions to the cmdlet, which you can find here.

Most important thing to remember: the Powershell script you provide to the cmdlet is copied to the VM, and then executed under the Local System account.

The goal

The goal of this blog is to do these tasks:

  1. Create a new VM using an ARM Template
  2. Install the RDS Sessionhost role on the new VM using the CustomScriptExtension
  3. Join the new VM to a domain using the JsonADDomainExtension
  4. Add the new VM to an existing RDS deployment, create a new SessionCollection with the new VM, and set some basic SessionCollection settings using the Invoke-AzureRmVMRunCommand.

Because of all the great blogposts and examples on ARM Templates & RDS deployments (a great example: part 1 & part 2 up to part 7 from Freek Berson), I will not go deep dive into this.
I will touch the most important sections and parts of the template to complete tasks 1-3.
Task 4 will be the main topic of this blog.


Before you can start with any of this, you will need your basic setup.
You will need to have a VNET, subnet(s), an Active Directory setup and a full RDS deployment with RDS Connection Broker, Gateway & WebAccess in place.

Task 1-3: Create VM, install RDS Role & join to the domain.

Create VM using ARM Template

To create a VM on Azure, you have a lot of possibilities: using the Azure Portal, using Powershell, using Azure CLI, etc etc.
Another great option is using an ARM Template.
As I said before, there are so many great blogposts and examples, so I’m not going into detail about this.
Below, you can find a screenshot from my ARM Template which will be used for the next parts as well.
ARM Template Create VM

Install RDS Role using CustomScriptExtension

In the ARM template, you can already start customizing your VM to your needs.
This can be achieved using the CustomScriptExtension.

You first create a Powershell script.
For this blog, I created a script with the following content:

This will install the RDS-RD-Server role required to add to our RDS Deployment.

Next, you will need to store this script on an Azure Storage Account so it can be used in the ARM Template.
PS script On Storage Account

To link a CustomScriptExtension to a VM, you define it in the Resources section of the VM.
You add a resource from the type “Microsoft.Compute/virtualMachines/extensions”. (line 192)
You give the resource the name from your VM and add a name for the action. In this case I named it Fix-RDS (line 193).
The script information is located in the “properties” section.
First, you set the extension type to “CustomScriptExtension” (line 203).
Next, you specify the script Uri (line 208): this is the Uri from the Azure Storage Account, the blob container and filename (see previous screenshot).
Next, you will enter the command that needs to executed (line 212)
Last part is the security information to download the Powershell script. In the example, I’m using the StorageAccountName & Key (line 213 & 214).


Join to the domain using JsonADDomainExtension

Once the VM is created in Azure, you want to be able to access the VM directly. This can be made easier if the VM is directly joined in your existing Active Directory.
This can be done using the JsonADDomainExtension.

To link a JsonADDomainExtension to a VM, you use the “Microsoft.Compute/virtualMachines/extensions” resource again, but this is not linked under your VM section. It’s a separate section, not linked or under the VirtualMachine section as you can see in the screenshot below.
You give the resource the name from your VM and add a name for the action. In this case I named it “joindomain” (line 229).
First, you set the extension type to “JsonADDomainExtension” (line 233).
Next, you enter the Active Directory name & the FQDN from the user to perform the join. This user needs to have permissions to perform the join in your AD.
Last part is the password from that user (line 244), but this is entered in the protectedSettings part for security purposes.

ARM Template JsonADDomainExtension

Now you have an ARM Template that completes Task 1 till 3.

Task 4: Add the new VM to your existing RDS Deployment.

All previous steps were all done using an ARM Template.
This template deployment can be started from the Azure Portal, Visual Studio (Code) or using Azure CLI.
But it can also be started from a Powershell script using New-AzureRmResourceGroupDeployment.
Powershell New-AzureRmResourceGroupDeployment

And once you have started your deployment, the next step is easy.
You wait until the deployment is finished using the Job ID.

As soon as the deployment is finished, you can further customize your VM, and finish the RDS setup.

The command

Invoke-AzureRmVMRunCommand has a few required parameters:

  • ResourceGroupName: the resource group where the VM is located in.
  • CommandId: The type of command you want to execute. In my example, I’m going to use “RunPowerShellScript
  • VM / VMName / ResourceID: the VM where the command needs to be executed on.

When using “RunPowerShellScript” as CommandId, you will need to specify which script needs to be executed.
Therefor, you use the ScriptPath parameter. Here, you specify the path where the script is located.
Important: the script needs to be on the computer/server executing the Invoke-AzureRmVMRunCommand, so you need to specify the local path on the local computer/server.

Last part are the optional parameters that you need to provide to your own script.
You can create a hashtable containing all your parameters for your script and provide the hashtable to the cmdlet.

In my example, I execute the command on the Connection Broker. This is the most ideal VM I think to do this, because you are sure the necessary cmdlets are installed.

There are a few important things you need to remember!

  • If you want to use blanks in your parameters, you must use double quotes and escape them, as you can see in my example below.
    So for example: you want to pass the parameter “sessionCollection” with the value “Micha Demo Collection”, then you need to add an item to the hashtable like this:
    “sessionCollection” = “"Micha Demo Collection“”
  • Your script can contain parameters, but the parameters cannot be set to manditory.
    So your parameter cannot have this property: [Parameter(Mandatory=$true)].
    Otherwise, you will end up a vague error like you can see below.
    I already posted this into the Powershell Advisor group to see if this can be fixed.
    Invoke-AzureRmVMRunCommand : Long running operation failed with status ‘Failed’. Additional Info:’VM has reported a failure when processing extension ‘RunCommandWindows’. Error message: “Finished executing command”.’
    ErrorCode: VMExtensionProvisioningError
    ErrorMessage: VM has reported a failure when processing extension ‘RunCommandWindows’. Error message: “Finished executing command”.

The script

Now comes the hardest part, because as I said in the beginning, the command started by Invoke-AzureRmVMRunCommand is executed on the VM under the Local System account!
As you may know, when you execute the Add-RDServer cmdlet, the cmdlet will check if the role you specify is installed on the new VM. If it’s not installed, the cmdlet will try to install the role.
And the Local System account of your Connection Broker does not have permissions on the new VM.

So how do we fix this?

As stated in the beginning, the script is copied to the target VM.
And the easiest way to perform and control a RunAs, is through a Scheduled Task.

So here is the solution:

  1. Create an inner script inside the outer script
  2. Output the inner script to the target VM disk
  3. Create a Scheduled task to run the inner script as a user with enough permissions
  4. Start the task and wait.

The outer script is the script you have on your local computer, containing parameters, the inner script, the scheduled task creation part and the wait job.

Sounds complicated, but really isn’t. Let’s go over it step by step.

The Parameters

The outer script starts with the parameters you want to provide. In my example, it is just these simple parameters:

The Inner script

We want to output this inner script to a ps1-file, without the outer script to execute the inner script. The easiest way to do this is by using a Here-String in Powershell.
You create a variable, and start with @”. All the text following after this, is interpreted by Powershell as text in 1 variable, no matter how many lines or tabs you enter, until you end it with “@

So for this script, I add the basic commands to add a server to an existing RDS deployment.
I also added a screenshot to show you how it looks in Powershell ISE.

Powershell Inner Script

Output the script

Easiest part: Just pipe your script variable to the Out-File cmdlet. This will write the inner script to the local disk of the server.

The scheduled task

A bit more difficult, but once you get it, it’s easy as 1-2-3.
First you create “an action“. This is what the Scheduled Task is going to execute. In my example: the Inner script in Powershell that we just created on the VM(line 2).
Next, you can specify some settings. In my example, I set the Compatibility level to the highest. So on a Server2016, this will be Server 2016 level (line 3).
Last part is registering the Scheduled Task, specifing the user credentials, the action and the settings created just before that (line 4)

Start the Task and Wait

This is easy, especially when you work with variables for your TaskName.
Now you simply execute the Task using Start-ScheduledTask.
And then you query the status from the Task until it is Ready

That’s it!


Invoke-AzureRmVMRunCommand is a great way to finish a ARM Template deployment.
Because if you can start both from Powershell, you know which servers are created, and you can easily finish installations, RDS deployments, etc.

This is not the only way to do this, but’s a great way, easily manageble and highly automatable.

Typing the characters

RDS HTML5 webclient update 1.0.1 – fixing the AltGr issues

RDS HTML5 webclient update 1.0.1 – fixing the AltGr issues


With the launch of the HTML5 Webclient for Remote Desktop Services (RDS) 2016, Microsoft has released a great feature.
Because all existing software can be used inside any browser, without rewriting the application.
We wrote an introduction about the Webclient, which you can find here:

Public Preview to GA

In July, when the Webclient went from Public Preview to GA (version 1.0.0), several updates were included in this release.
Some highlights:

  • Single Sign On (SSO) experience for the users
  • Time Zone Redirection
  • Improved sign-in experience
  • Improved error messages & handling
  • Copy&Paste text through the clipboard using Ctrl+C & Ctrl-V
  • etc

Update 1.0.1 fixing the AltGr issues

Despite all these great features, there was still an big issue, especially for European users: the AltGr keystrokes did not work correctly (or at all).
So for most European keyboards, you could not type @, , { or any character using the AltGr key.

But now, Microsoft freshly released update 1.0.1 for the Webclient, fixing this bug.
(at the time of writing this blog, the release notes are not yet online, but you should be able to find them here: What’s new for the Remote Desktop web client?)

Typing the characters

I installed the update on my existing deployment and I’m able to type all these characters inside the Webclient!

How to update?

When you want to update your current Webclient, you just have to follow these simple steps:

  • Open an elevated PowerShell prompt on the RD Web Access server
  • Download the latest available version of the web cient
  • If you want to test the update first, you can Publish the client to Test slot in your deployment using this cmdlet:

    You can access this Test deployment using this url: https://<<Your-Deployment-FQDN>>/RDWeb/webclient-test/index.html
  • If you tested the update and want to put it online, you can use this cmdlet:


That’s it, your deployment is updated to version 1.0.1, with all bugfixes, including the AltGr fix.

RDmi has evolved into Windows Virtual Desktop

RDmi has evolved into Windows Virtual Desktop

RDmi has evolved into Windows Virtual Desktop


Last week at Ignite, Microsoft announced the new name and model for RDmi: Windows Virtual Desktop or shortened to WVD (follow me on Twitter or search for #RDmiEvolved and #MsWvd)
A few things have changed since my latest blog about RDmi ( which I will describe below.
We already knew a few things in advance, but we were not allowed to share them in public, until now!

From DIY to PAAS

The first change is the new delivery model for WVD.
RDmi would have been a group of services that needed to be managed by yourself or your CSP/MSP like ASPEX, a Do-It-Yourself (DIY) model.
Microsoft has changed this model from a DIY service to a PAAS service, fully managed by Microsoft. You can compare it to the Azure SQL Database, where Microsoft handles the SQL Deployment.
This is the same for WVD: Microsoft handles the services, including HA, backup, etc. So the RDmi Infra Tenant services (Gateway, Web Access, Connection Broker & the new Diagnostics role) are all managed by Microsoft.

I will get into detail about the entire deployment in a future blogpost, coming soon.
You can also attend CloudBrew on 12&13 October where I will give a session about RDmi/WVD and demo this deployment.


There was no known licensing information for RDmi, except hosting the RDmi Infra Tenant services. With the shift from DIY to PAAS, Microsoft changed its licensing model for WVD.
The WVD requires one of these licenses:

  • Microsoft 365 E3/E5
  • Microsoft 365 Business/F1
  • Windows E3/E5

For all other users/customers is no licensing information available yet. I will keep you updated about this on Twitter & my blog.

Backend Support

The WVD will support multiple experiences: Virtual Desktops & Remote Apps, but also multiple backend system:

  • Windows Server 2012 R2
  • Windows Server 2016
  • Windows Server 2019 (now in GA)
  • Windows 10 Enterprise (more on this in next topic)
  • Windows 7 Enterprise

Especially the last OS is an interesting one.
If you host your Windows 7 Enterprise on Azure using WVD, you get free Extended Security Updates, to support your upgrade to Windows 10!

Windows 10 Enterprise Multi-Session

Another big announcement is the multi session Windows 10.
Microsoft will soon release a Windows 10 version on Azure which will support multiple concurrent sessions. This is a great step forward for hosting Virtual Desktops on Azure. Because this brings along support for Modern Apps like Edge, Cortana, the Microsoft Store & Office 365 ProPlus (like Outlook, OneNote, OneDrive) support, all combined with semi-annual updates.
Windows 10 Enterprise for Remote Sessions

I will write a blogpost in the next couple of weeks about my test results using this OS.
This will also be in the demo’s on CloudBrew!


WVD will be a great solution to publish desktops and applications if you have the required licenses available.
As soon as the other licensing possibilities are available, WVD will be a solution to deliver desktops and applications to your customers.

But this should not stop you from your migration to Azure now! You can already migrate to Azure, giving you a head start for WVD.
Pavithra Thiruvengadam gave a great session at Ignite about Migrating virtualization environments to Azure, mentioning ASPEX as one of the Microsoft Azure Hosting Partners!
Watch the video here:

This is a short recap about WVD announced at Ignite. More detailed information and test results will be posted later on…

Blog announcement:
WVD service page:

Migrate/upgrade RDS Deployment to new Connection Broker, even on Azure, using my new Powershell Module


[UPDATE 2019-03-10] I did an update on the module introducing some new features. You should read the update first before continuing here: ExportImportRdsDeployment module has been updated and it has Backup functionalities now

As documented in this article, the first step to upgrade your Windows Server 2012R2 Remote Desktop Services (RDS) deployment to Windows Server 2016 is upgrading your Connection Broker.
This can be done using an in-place upgrade, but this not always ideal:

  • The in-place upgrade takes quite some time depending on various factors, like hardware, installed software, etc.
  • The upgrade can fail, causing you to rollback and increases downtime
  • There are numerous articles that discourage an in-place upgrade due to performance issues, legacy application problems, …
  • On Azure, an in-place upgrade is not supported! So you cannot upgrade your Windows there.

ASPEX has a customer that was using a Windows 2012R2 RDS deployment and we told him about the HTML5 webclient that was in Public Preview at that time, which would be a great asset to the end users.
The big problem: the HTML5 webclient requires a 2016 RDS Deployment.
We suggested to upgrade the RDS deployment from 2012R2 to 2016, but the customer requested a minimal downtime and a phased migration.
This ruled out an in-place upgrade, so I started coding…

The solution

I created a Powershell module that contains 4 functions. Each function is a step in the process to migrate your RDS deployment from one Connection Broker to another.
The module will allow you to export your existing Session Collections and RD Servers with all configuration settings, and remove them from the old Connection Broker.
Then you can import everything back into the new Deployment, connecting the RD Servers to the new Connection Broker and recreate the Collections.

There are several scenario’s where you can use this module:

  1. Migrate from one Connection Broker to another
  2. Upgrade from a 2012R2 to 2016/2019 RDS deployment
  3. etc

The module has been made available in the Powershell Gallery, so you can easily install and use it on any Windows Server.

The module will only migrate these RD roles: RD Gateway, RD Web Access & RD Session Host
The other roles (RD Connection Broker & RD Licensing Server) should already be installed on the new Connection Broker


Only Session-based Desktop Deployments (Session Collections and Personal Session Desktops) are currently supported!
If you have a Virtual machine-based desktop deployment (using a Virtualization Host), you should not use this Module!

You should always make sure you have a backup of your Connection Broker config before you start.
Testing the module on your Dev environment is always a best-practice.


The overview

Deployment on the old Connection Broker

This is how my test deployment looks like:

1x server as old Connection Broker & Licensing: MICHA-P-RDB-001
1x server as Gateway & Web Access: 2019-TEST-RDG1
6x servers as Session Hosts: MICHA-P-RDH-001 ==> 006
Old CB Deployment Overview ServerManager

I have 3 Session Collections (1 with Remote Apps and 2 with Remote Desktops) and 1 Personal Session Desktop Collection.
These are all divided over the available Session Hosts, as you can see in the screenshots below.
Old CB Collections Overview ServerManager Old CB RemoteApp Collection Overview ServerManager Old CB Collections Overview Powershell

New Connection Broker

1x server as new Connection Broker & Licensing: 2019-TEST-CB
I only installed the 2 roles on the 2019-TEST-CB machine.
It is recommended to install the Licensing role on the new Connection Broker server.
New CB Installed Roles  New CB Deployment Overview ServerManagerNew CB Deployment Overview Powershell


For this blog, I’m going export the Session Collections, Sessions Hosts, Gateway and Web Access servers from MICHA-P-RDB-001 to 2019-TEST-CB

The migration


To install the Module, you simply run these 2 commands:

 Old CB Install & Import Module New CB Install & Import Module

The module is uploaded to the Powershell Gallery, therefor you can easily install it, and it is signed using a Code Signing certificate.
If you get a message regarding the Nuget provider, you should confirm to install
the module


Install Module

Install the module on the old Connection Broker:


First step is to export the Session Collections. The module will export the collections to a XMLfile, so it can be easily migrated to the new Connection Broker.
You export the collections using this command:

You must specify the ConnectionBroker and optionally the XmlFile. And if you add -Verbose, you will get detailed steps in the progress
Old CB Export Collections Start

When finished, you will get the location of the XMLFile (default: in C:\temp, unless specified otherwise).
Old CB Export Collections Finished


Next step is to export the Deployment (including the servers).
You export the deployment using this command:

You must specify the ConnectionBroker and optionally the XmlFile. And if you add -Verbose, you will get detailed steps in the progress
Note: You have to confirm that you exported the Session Collections before running this step.
Old CB Export Deployment Start

When finished, you will get the location of the XMLFile (default: in C:\temp, unless specified otherwise).
The error message (as displayed below) is default behavior due to the removal of the Gateway Role from the deployment.
Old CB Export Deployment Finished

Export Files

When both exports are completed, you will find the XMLfiles in the export location.
These files should be used when importing to the new Connection Broker.
Old CB Export XmlFiles


Install Module

Install the module on the new Connection Broker

Import Files

Copy the XMLfiles to the new Connection Broker, unless exported to a shared network location.
You also need the certificate(s) for all 4 roles in the deployment: RDGateway, RDWebAccess, RDPublishing & RDRedirector
In this test migration, I used a wildcard certificate for all 4 roles.
I placed all files in the C:\temp folder
New CB Xml & Pfx Files


First step is to import the Deployment (including the servers).
You import the deployment using these commands:

You must specify the ConnectionBroker and the XmlFile, and the 4 certificate locations and passwords. And if you add -Verbose, you will get detailed steps in the progress.
New CB Import Deployment Start

When finished, you will get an summary of the imported deployment.
New CB Import Deployment Finished


Next step is to import the Session Collections.
You import the collections using this command:

You must specify the ConnectionBroker and the XmlFile. And if you add -Verbose, you will get detailed steps in the progress.
New CB Import Collections Start

When finished, you will see all Collections that are imported, including the published RemoteApps.
New CB Import Collections Finished

Overview after the migration

When you review the Server Manager, you will see that the entire Deployment is migrated.
New CB Deployment Overview ServerManager After Import

Also the Collections are completely migrated.
New CB Collections Overview ServerManager

And the Personal Session Desktop Collection is also available again.
New CB Collections Overview Powershell


Using this module, you are able to migrate your entire deployment in a controlled manner, on any platform (like Azure) and faster than performing an in-place upgrade.

You also completed step 1 and 2 from the guide in this article.

You can simple follow the guide further, or you can install your new Session Hosts, Gateway(s) and Web Access servers, and replace these in the new Deployment.


RDmi update: RDmi compared with RDS




As we have posted in our previous blog (Next generation architecture & HTML5 for RDS Hosting), ASPEX and Microsoft are still working closely together to test and improve the Remote Desktop Modern Infrastructure or RDmi.

We also talked about RDmi on two conferences:

  • first time on our Technical Partner event, on December 12th 2017
  • second time on ITPROud, the latest IT Conference for IT Pro’s, on March 14th 2018

Microsoft allowed us to give these presentations under NDA to all attendees, including a live demo of RDmi!

In this post, we will show you what you have missed from the conferences (without the information covered by the NDA), the key differences between the classic RDS and RDmi, and how an RDmi will look like in the near future.

Continue reading