Deploying Windows 10 Virtual Desktop Infrastructure on Windows Server 2016 (Technical Preview)
Three years back I wrote a blog post on Deploying Windows 8 Virtual Desktop Infrastructure on Windows Server 2012 that has been wildly popular and received lots of blog comments. With the release of Windows 10 anticipated within the next month, I felt it would be appropriate to do an update to this blog post. This time, I will show how to deploy Windows 10, using NVIDIA GRID K1 graphics cards, RemoteFX, and Windows Server 2016 (not the official name, still being called ‘Technical Preview 2’). The Windows Server 2016 host is an HP DL380 Gen8 server with two GRID K1 cards and will act as my Remote Desktop Virtualization Host. For the RDS Connection Broker/Gateway server, I’ve deployed Windows Server 2016 into a virtual machine that will be externally facing.
To get started, I’ll show the experience of installing Windows Server 2016 (Technical Preview 2 build 10074) bare metal. Boot from the installation media and click Next:
Click Install now:
Select Windows Server Technical Preview 2 (with local admin tools)
and click Next:
Accept the terms and click Next:
Select the Unallocated Space and click Next:
Monitor the installation progress:
Setup the Administrator account by clicking OK:
Enter and repeat a password:
First thing I noticed, unlike previous versions of Windows Server, there is no Server GUI by default! Fantastic. Great work Microsoft. Server Manager launches automatically, but there’s no Explorer shell. To add that, navigate to Manage -> Add Roles and Features:
Select Role-based or feature-based installation and click Next:
Leave default and click Next:
In Features, scroll down and expand User Interfaces and Infrastructure. Select Server Graphical Shell and click Next:
Optionally you can select to restart the server automatically. Click Install:
Once complete, click Close:
If the server didn’t automatically reboot, you can initiate a reboot by running ‘shutdown –f –r –t 0’:
Next, because this is an HP ProLiant server, I’m going to install all the Windows Drivers by mounting the Service Pack for ProLiant media and doing an automatic installation. Be sure to install any available firmware or Windows Drivers for your applicable server. Fortunately, the latest version of HP SPP is already Windows Server 2016 ready, that was a nice surprise.
Once the server drivers are installed, I installed the NVIDIA Graphics Drivers for my GRID K1 cards. You can find these on NVIDIA’s website. Click Agree and Continue:
Select Express and click Next:
Click Restart Now when complete:
Navigating to Device Manager, I noticed all drivers were installed (no unknown devices), including my NVIDIA GRID K1 cards:
Next, I’ll install the Hyper-V and RDS Virtualization Host roles. From Server Manager, click Add Roles or Features. Click Next:
Leave defaults and click Next:
Scroll down and select Remote Desktop Services:
Click Next to bypass features:
Select Remote Desktop Virtualization Host:
Review the roles and features that will be automatically installed and click Add Features:
Select the appropriate network adapter(s) and click Next:
Leave defaults or customize if desired and click Next:
Check the box to Restart automatically. Select Yes:
A server reboot may be initiated. If so, log back in and review the progress. Click Close:
Next, I’ll setup my Windows 10 Master Virtual Machine in Hyper-V. In Server Manager, select Hyper-V. Right click the Server and click Hyper-V Manager (you can get to this from the start menu as well):
On a new installation, no Virtual Machines exist. To verify that the NVIDIA GRID K1 cards are available for RemoteFX, click Hyper-V Settings:
Select Physical GPUs, and click the drop-down to view all GPUs. Ensure each GPU has the ‘Use this GPU with RemoteFX’ selected. Click OK when finished:
For my Windows 10 Virtual Machine, I’m going to use Windows 10 Pro Insider Preview (build 10130).
Click New, Virtual Machine:
Enter a name for the Master VM. For my environment, I used Win10-M. Click Next:
Select Generation 2:
Enter a Memory value and click Dynamic Memory:
Select a network connection:
Enter a VHD size (and location if desired):
Select Install from bootable image and browse to the Win10 ISO:
We need to modify a couple properties. Right click the VM and click Settings:
For starters, I’ll bump the Processors to 2 (defaults to 1 vCPU):
Click Add Hardware and select RemoteFX 3D Video Adapter:
Optionally, I can modify the number of monitors, resolution, and dedicated video memory available to the VM:
Right click and select Connect:
The virtual machine will automatically boot to the Win10 ISO:
Click Install Now:
Accept and click Next:
Select the Unallocated Space and click Next:
Review the installation progress:
Click Use Express Settings:
Click My Organization and click Next:
Click Join a domain and Continue:
Enter a username and password and click Next:
Optional: Install any applicable Windows Updates (this may take a while):
For my build, some of the Windows updates required a reboot:
This would also be the ideal time to install any base image applications that any user would need access to (Microsoft Office, Adobe Reader, etc.). Normally, this is when I would also Sysprep the VM in order to create an Automatic Pool of Virtual Desktops. Unfortunately, the build of Windows 10 that I am using is unable to Sysprep. After fighting with it for a while, I decided to bypass Sysprep for now, and just clone the VMs using Hyper-V. For more details on the errors I encountered, see this blog post. Unfortunately the fix (stopping the tiledatamodelsvc) did not resolve my issues (Error SYSPRP Failed while deleting repository files under ‘C:\ProgramData\Microsoft\Windows\AppRepository’). I’m hopeful Microsoft will have this fully resolved by the time Windows 10 is ready to ship, otherwise it will be fairly difficult to deploy in Enterprise environments as most every deployment tool relies on Sysprep…
We’ll come back to the Windows 10 Virtual Machine in a little while. For now, let’s configure our RDS environment for VDI.
I’ve deployed a second Windows Server 2016 VM as I mentioned. This server will act as my RD Connection Broker, RD Web Access, and Gateway Server (VMWS16RDS01). From Server Manager on VMWS16RDS01, I need to add the RDS Virtualization Host (DL380Gen8). Right click All Servers and click Add Servers:
Type the server name and click the arrow to add it to the selection:
With both servers added, I’ll select Manage -> Add Roles and Features:
This time I’ll select Remote Desktop Services Installation and click Next:
Select Standard Deployment and click Next:
Select Virtual Machine Based Desktop Deployment and Click Next:
Move the RD Connection Broker (VMWS16RDS01) over using the arrow and click Next:
Move the RD Web Access server (VMWS16RDS01) over using the arrow and click Next:
Move the RD Virtualization Host (DL380Gen8) over using the arrow and click Next:
Select Restart automatically and click Deploy:
Review the installation progress:
Once completed, click Close:
Next, we’ll configure the RD Gateway by clicking the Green + Button in the topology:
Move the RD Gateway (VMWS16RDS01) over using the arrow and click Next:
Enter a Fully Qualified DNS Name (FQDN) for the remote access URL and click next:
Review the progress and click “Configure certificate” when completed:
For my environment, I have a pre-existing certificate in .PFX format that I will use, so I’ll click Select existing certificate:
Enter the path to the existing certificate, password, and click OK:
Click Apply to complete the step for each service. Rinse and repeat this process until each Role Service has a certificate assigned. Once finished, click OK to close:
Next, we need to add the RD Licensing Server. If you already have an RD Licensing Server, be sure to add it to Server Manager, then click the Green + button above RD Licensing:
Move the RD Licensing server (VMWS12DC01) over using the arrow and click Next:
Click Review RD Licensing properties for the deployment:
Select the licensing mode (Per Device or Per User) and click OK:
Review the topology to make sure each step has been completed. We’ll come back to create our initial collection.
Since I can’t use the automatic provisioning process of RDS 2016, I’ll export and import the Win10 VMs and join them to the domain manually. In Hyper-V Manager, right click the Windows 10 Master VM and click Export:
Enter a path and click Export:
Monitor the progress under the Status column:
Once completed, the status field will be blank. Click Import Virtual Machine on the Actions pane:
Browse to the path of the Windows 10 Master VM and click Next:
Select Copy the virtual machine and click Next:
Click Store the virtual machine in a different location and enter a path for each option (I prefer to make this unique for each VM, i.e. ‘Win10-01’) and click Next:
Enter a path for the VHD location (I prefer to make this unique for each VM, i.e. ‘Win10-01’) and click Next:
Review the progress during import:
Once imported, it’s good to rename the Virtual Machine to avoid confusion:
Next, I’ll boot the VM, rename it to match the Virtual Machine name, and join the domain. These steps are normally taken care of by the automatic deployment process, but since Sysprep is broken I can do this manually. Once joined to the domain, I’ll login to verify access.
In Server Manager on the RDS server, navigate to Collections. In the Tasks section, click Create Virtual Desktop Collection:
Review and click Next:
Enter a Name for the Collection. This will be the name users will see when they connect through the Gateway or RD Web Access servers. Click Next:
Select Personal virtual desktop collection. Normally I would also select Automatically create and manage virtual desktops, but this requires the Master VM to be Sysprep’d to create. With Automatic creation deselected, click Next:
Select the Virtual Desktops on the Hyper-V host and click Add (can optionally select multiple if more than one VM was imported). Click Next:
Select Enable automatic user assignment and click ‘Add the user account to the local administrators’. Click Next:
Enter the usernames or security groups of users assigned to this collection:
Review and click Create:
For external access, a Network Address Translation (NAT) needs to be setup, along with an External DNS record pointed at the NAT address. In the firewall, the following ports need to be allowed:
RD Web Access/Gateway Server:
No ports need to be opened to the VDI desktops or the Virtualization Host, only to the RD Web Access/Gateway server.
To make the user experience a little smoother, I’ll setup an HTTP redirect on the RD Web/Gateway server. In IIS, navigate to Server\Sites\Default Web Site. Double click HTTP Redirect:
Click Redirect requests to this destination and enter https://ExternalFQDN/RDWeb. Click Only redirect requests to content in this directory. Click Apply:
Review the changes and ensure they applied properly:
Now, when users browse to http://ExternalFQDN instead of seeing the default IIS page (below):
Users will now be redirected to the correct authentication page. Now we’re ready to login! Enter the domain\user name and password. Select This is a private computer and click Sign In:
Click the RDP icon to connect:
Now, a domain user (DEMO\Dane.Young) is assigned as a local administrator to the Persistent Virtual Desktop. We can see the VM name is Win10-01 and the connection was brokered successfully.
At this point I’m ready to get started using my persistent Windows 10 Virtual Desktop, brokered using Windows Server 2016 on a Hyper-V 2016 host! I hope you’ve enjoyed this blog post and that I’ve shown you how quick it can be to get up and running using a 100% Microsoft solution. I am excited to see Windows 10 become available, and start deployments using other brokers including Citrix and VMware. For now, my Windows 10 RDP and RemoteFX environment will have to suffice.
If you have any questions, comments, or just want to leave feedback, please feel free to do so below.
Having trouble with the Nvidia GRID driver: most of the ones I’ve tried say “wrong operating system”; the one that did install doesn’t work: Device Manager reports (paraphrasing) “driver stopped working with Code 43”. The screenshot clearly shows you’re using 347.52, but which “flavor”?
The Nvidia driver search at http://www.nvidia.com/Download/index.aspx?lang=en-us shows two “product series”: “GRID Series” and “NVIDIA GRID vGPU”. The latter then offers support for XenServer and vSphere but not Windows Server; the former offers Server 2012 but not 2016.
Any thoughts? Thanks.
BTW, at least in TP4, there’s an option during install to include the graphical shell.
I found that the 347.52 Quadro/Grid Nvidia driver works. Shoot me an email if you cant find it online and Ill send it over to you.
Use the windows 10 driver on server 2016. It worked for me with the GRID K2
Thanks Ryan, William! I’ve tried out the 347.52 Windows 10 driver, with the same lack of result. Planning to double-check the power connection, and if that doesn’t work then try it in another machine. Will let you know!
Breakthrough! Turns out the drivers fail when you have more than a terabyte of RAM! Pulled have the memory boards, and voila! it’s happy again.
Thanks everyone for your help!
I would have never thought of that. That is a pretty rare limitation to have!
From your configuration if user01 is assigned to a VDI (eg: Win10-01) and logged on, will another user (eg: user2) able to connect to WIn10-01 in future when user01 has logged out? We sometimes met the problem that the collection cannot be created because of some apps or sysprep error and we are thinking how to get rid of the problem, but our VDIs need to be shared freely by any AD users.
Secondly, if you need to apply patches or install new software, do you need to do it for each VDI manually? Is it possible to all VDIs in batch?
Have you had any trouble with profile disks on Server 2016? I’m testing VDI with a windows 10 image and profile disks just doesn’t work. Any thoughts? I’ve set it up in Server 2012 R2 RDS and it works no problem.
I had trouble sysprepping win 8 originally and the same issues with win10. this is because of the “apps”. they need to be removed in order for sysprep to finish without error. I had success with these two powershell commands.
Get-AppXProvisionedPackage -online | Remove-AppxProvisionedPackage -online
Get-AppxPackage -AllUsers | Remove-AppxPackage