- Privileged access workstation (PAW) and lateral movement - Wed, Jul 14 2021
- Securing timeouts in Remote Desktop Session Host (RDSH) and Virtual Desktop Infrastructure (VDI) environments - Wed, Sep 23 2020
- Manage OneDrive caches with Windows Storage Sense - Thu, Jul 9 2020
However, a recent post from Eirik Haavarstein indicated that it was possible to use UPD on Citrix XenApp systems. Doing so provides not just user profile persistence, but also a solution to handling certain file types. These include Outlook OST files, Windows Search and other caches that traditionally perform badly in RDSH or VDI (virtual desktop infrastructure) environments. The article also mentions briefly that they also performed testing on Windows client systems. So what I set out to investigate was – just how easy, and how feasible, is it to use UPD on Windows 10?
Firstly, does Microsoft even support UPD on Windows client systems?
The official answer is yes – for VDI only. There's no detail as to what flavor of VDI this referenced, so I assume it means VDI of any type. However, as with the UPD feature on RDSH, you may find documentation and support to be a bit, shall we say, lacking. It's clear that Microsoft doesn't seem particularly interested in UPD as a key feature, which is a shame. In certain situations, it can provide an easy way of providing a persistence solution that gets around some of the major drawbacks of a traditional roaming profile.
So, assuming we are using Windows 10 VDI (or maybe you're running Windows 10 physically and just want to see if it might provide an easy but unsupported solution), how do we go about setting this up?
First, you need a file share to hold the profiles you will be mounting. Dependent on user volume, you may want this to be quite sizeable, because UPD captures the entire user profile, and on Windows 10, profiles have gotten rather large. It would also make sense to use fast storage for this where possible.
UPD isn't as sensitive as roaming profiles are to transient network conditions. This is mainly because it is only writing to a single file, and large amounts of files are just as bad for profile performance as sheer size. However, for something that is going to be central to the entire user experience, I would definitely recommend using fast storage. In addition, ensure that you fully patch your file server before using UPD.
You need to set both NTFS and share permissions so that all devices accessing it have full control. Attaching and detaching the VHDX file occurs in the context of the computer account, so either individually add the accounts for your client machines or use the Domain Computers group.
Next, inside the file share, create a folder for each operating system for which you will be using UPD. You'll need to subdivide them by profile version number, so Windows 10 RTM and 1511 can share a folder, but Windows 10 1607 will need a separate one. In this case, we have simply created three folders, one each for Windows 10 1511 (and RTM) and Windows 10 1607, and a separate one for Windows Server 2016.
After this, we need to create a template VHDX file for our systems using PowerShell. It doesn't matter which operating system you create the template VHDX from, but I used Windows 10 1607 just to err on the side of caution. Open up an administrative PowerShell session and run the following command (changed to fit your file share and path):
(get-wmiobject -ns root\cimv2\terminalservices -class win32_tssessiondirectory).createuserdisktemplate("\\SERVER\SHARE\Profiles",1)
You can change the last value (1) – this is for the size of the template profile in GB. You may want to make it a little higher than 1 GB if you anticipate any bloat in profiles. For a production environment, 5 GB may be a better size to start with, assuming you have the space available.
You should now see a template VHDX file created in the share you specified.
You now need to copy this file to each of the OS-specific subfolders you created.
We now need to enable UPD on our Windows 10 clients. To do this, open up an administrative PowerShell session again and run the following command (changed to fit your profile share and path). If you have multiple OS version folders, you will need to point each client to the correct folder path for its operating system. For instance, this is what we would run on Windows 10 1607 machines:
(gwmi -ns root\cimv2\terminalservices -class win32_tssessiondirectory).enableuservhd("\\SERVER\SHARE\Profiles\Win10-1607","
And this is what we would use on Windows 10 1511 machines
(gwmi -ns root\cimv2\terminalservices -class win32_tssessiondirectory).enableuservhd("\\SERVER\SHARE\Profiles\Win10-1511","
After running this, you should see the following output:
This command creates a set of registry values in the key:
The UvhdEnabled value indicates whether UPD is enabled on the endpoint or not.
The UvhdShareUrl tells it where to store the UPD profiles for each user.
The UvhdRoamingPolicyFile value tells it where to look for a configuration XML file. This should always be set to the default (C:\Windows\RemotePackages\RDFarm\UvhdRoamingPolicy.xml) and should always have the following content:
Now you're probably thinking that this would be easy enough to enforce with Group Policy. Indeed, it would. A Group Policy startup script (filtered by devices) that runs the initial get-wmi command would suffice to activate UPD on target machines automatically. Bear in mind that the different OS versions need a different path in the command, so you'd probably have to use a WMI filter on the Group Policy Object (GPO) to ensure each OS points to the right path. The same applies to the registry values, which you could enforce with Group Policy preferences within the same GPO.
If you need a WMI filter to differentiate between different Windows 10 versions, use these:
And now we're completely set up; we just need to test.
When you log on, you should see a VHDX file created in the subfolder for the target operating system as below. There is one for each user, named by security identifier (SID).
Users logging on via UPD should not have roaming profiles or mandatory profile paths set on the Active Directory (AD) object, or there may be problems. If a local or roaming profile already exists on the endpoint, UPD will rename this profile to a "backup" folder.
The user's profile folder will simply appear to be a mounted VHD rather than a traditional filesystem folder, but applications and data will write to this seamlessly.
Each user can only have one UPD session at a time. The reason for this is that the session locks the VHDX file exclusively, as you can see.
You also cannot apply UPD specifically to subsets of users. It is a device-level setting, so an administrator logging on to the endpoint will also create a UPD profile.
Logon time seems to vary; the first logon can be around one to two minutes, while subsequent logons might vary from about forty seconds up to a minute. I tested this in a small lab using spinning disks though, so you should expect better performance in enterprise situations.
Occasionally, the file lock will not release cleanly when the user logs out, and this will fail to remove the junction point for the user's folder in C:\Users. You can rectify this by closing the open handle on the file server or by simply restarting the client endpoint that has the VHDX file locked. Do not, if possible, perform a hard reset on any devices that have open file locks; this can cause the profile to become corrupted. To prevent this lock issue from occurring, it may be useful in VDI environments to set the devices to restart whenever a user logs out or disconnects (see this thread for a discussion of doing this on Citrix XenDesktop).
An administrator wishing to edit the profile of a user not currently logged in can mount the VHDX file and edit it directly. However, remember to unmount the file after completing the editing.
You can use UPD on Windows 10 using the technique described above. It provides a quick and low-overhead method of setting up user persistence without any extra expenditure. In addition, it roams the entire user profile, overcoming some of the limitations of a traditional roaming profile. It also deals with the performance issues of things like Outlook OST files in a VDI or RDSH environment.
UPD does require a lot of storage overhead and is limited to single sessions. Moreover, the occasional file lock means you may have to put in some mitigations against this. What's more, the habit of storing the VHDX file with the SID means that in high-volume environments, it is sometimes tricky to work out which UPD belongs to which user.
It is also worth mentioning that FSLogix has taken the UPD concept and improved it with their Profile Containers product. Profile Containers works in much the same way, but has added support for older client operating systems like Windows 7 and 8, removed the file locking issues, improved the logon times, appended user names to the VHDX file names, and also has much more readily available support than Microsoft with regard to the product. Admittedly, this comes at a (fairly low) license cost, but there is more in the FSLogix suite than just the Profile Containers part. If you're going to use a technology like UPD in a busy production environment, then the price for FSLogix is in my opinion worth paying.
Subscribe to 4sysops newsletter!
Thanks to Claudio Rodrigues and Eirik Haavarstein for originally bringing this technique to my attention, and to Toby Phipps for providing Claudio with the commands to enable UPD in this fashion.