Welcome to part 3, the last part of this continuing series of blog articles that explore the differences between Citrix Profile Containers and FSLogix. In part 1 I laid out my configuration and the environment I am testing in. Part 2 went over FSLogix and how its “AppX optimization” operates. In this article I’m going to explore how Citrix Profile Containers implement their “AppX optimization” and I’ll investigate how it works and the findings I’ll come across.
To start my investigation, I’ll do the same initial set of steps I need to gather all the information around the logon process. I’m going to run a Process Monitor capture and follow along with their log files to try and provide some context for what each solution is doing — with a focus on Citrix Profile Containers in this article. Specifically, I want to explore the enhancements the solutions attempt to do to increase performance with AppX packages.
I want to highlight something that came to my attention during the course of researching this information. I originally started this article with version 2402 LTSR of the Citrix Virtual Apps and Desktop’s product. In version 2402LTSR, the only ‘optimization’ available for Appx/UWP apps was an app-roaming feature.
A VERY big change occurred on Citrix Virtual Apps and Desktops 2507 LTSR. Citrix released a feature called “Enable UWP app load acceleration”. This feature promises to make a difference in how long the AppX phase of a logon took. I’ll investigate this claim in this article alongside the prior version.
To capture the logon information I’ll use the ControlUp script action “ProcMon – Trace System Activity”
I defined the Duration to be 200 seconds to ensure that I’ll capture the entire logon process. Process Monitor (procmon.exe) needs to be stored in a folder readable by the machine. In my example, I have procmon.exe within the C:\swinst\sysinternals folder with the process monitor log stored in the D:\ProcMonLogs folder.
It’s important to note that procmon, when run at the system level, captures about 1GB of information per minute (sometimes a bit more, sometimes less, but this seems to be the average).
Once the Procmon script started, I logged into the machine. It’s important to note that I am using profiles that exist — that is I’ve logged into a machine previously that created these profiles. The reason why this is important is that a first logon where a profile container needs to be created does slow down the logon process as it has a series of steps required to get the profile container created and ready. Another note for this document is that procmon does increase logon duration but it tends to do so proportionally from a non-procmon monitored logon.
Running the ControlUp Analyze Logon Duration action gave me the output to examine the logs for the timestamps that related to user profile management and the AppX phases:
In the output for the logon I can clearly see the Citrix Profile Container stage at the start of the process take 3.2 seconds… Not too bad. But the “AppX – Load Packages” phase still seems to take a very long time… about ~37 seconds. Does the Citrix Profile Management Log file say anything occurred?
Examining the Citrix Profile log file (found in C:\Windows\System32\LogFiles\UserProfileManager), I can look to see if anything in the log occurred at the 8th minute, 42 second-ish phase:
There is nothing that occurred during that time, the log goes from 08:18.416 to 10:47.136. This might make some sense as the UWP App Roaming feature appears to ensure that pre-user AppX packages are able to roam. The packages that affect logon times tend to be system-level packages. Per-user packages can be mounted at any time after a user logs on so I would think the expectation of them processing anything during a logon would be very low. And this appears to be the case for me here.
Using the Process Monitor log, I looked to see if anything was read regarding AppX or UWP.
I can see that Citrix runs a Powershell command, and sure enough it’s to “RegUwpApps”. I did not have any per-user AppX packages loaded (my registry value, as highlighted in the screenshot, shows “NAME NOT FOUND”).
This was the command:
PowerShell.exe -WindowStyle hidden -Command "(Get-Item HKCU:\Software\Citrix\UserProfileManager\RegUwpApps).Property|%{Get-ItemPropertyValue HKCU:\Software\Citrix\UserProfileManager\RegUwpApps -name $_}|%{Add-AppxPackage -Register $_ -DisableDevelopmentMode}"
When looking at the procmon logs, this powershell command ran past my process monitor capture (90 seconds later it was still running). This does mean that the Citrix User Profile log doesn’t appear to log when this action occurs and nothing is present in the event log. I suspect the long launch and operation of this powershell command is due to me using a Powershell profile which can take between 5 and 30 seconds to run and all the modules installed on my machine which are automatically loaded during the powershell startup. Citrix may benefit from starting the powershell process with -noprofile.
The end result of Citrix Virtual Apps and Desktops (CVAD) 2402 and optimizing for logon duration with AppX packages is there is none. And enabling the UWP App Roaming (if it’s not needed) could add to logon times because Powershell can take CPU time away from other tasks.
Citrix has invested some time in optimizing logon times with CVAD 2507. This is claimed to be done by this feature, “Enable UWP app load acceleration”.
In the first article in this series I enabled the UWP App Roaming for 2402, I’m going to continue here to describe what I did to enable UWP App Acceleration in CVAD 2507.
To enable the UWP app load acceleration is set here:
| Items | Description |
| Enable AppX package load acceleration | PathToAppRepositoryContainerStore Reg_SZ \\mwss01.jupiterlab.com\fileshare\Profiles\CitrixAppXAcceleration |
Simple enough, set this registry value to a path where a VHDX can be saved and read from.
With this value set, I’m going to run process monitor and start tracing the machine and logon.
After logon, I ran Analyze Logon Duration to breakdown the logon into phases:
It looks like enabling this UWP App Acceleration removes AppX from being processed!
This is huge! Typical time spent in AppX Packages ranges between 20-30 seconds in my environment.
However, there appears to be a drawback that I can’t figure out. I had large gaps of time and when I investigated it was Default Associations being applied. I added when Default Associations are started and when they are ended to the Analyze Logon Duration script. The Default Associations is started asynchronously but if it doesn’t complete before other processing then it will block logons for the phase identified (Default Associations appears to apply at the User Profile and Group Policy phases). I wanted to see if a Azure Virtual Desktop machine was having the same thing with Default Associations applied multiple times — was this a Microsoft issue or is something else initiating multiple Default Associations applications?
Default Associations are set via Group Policy:
Configuring this allows you to setup file type associations, essentially what program should launch a particular file type or if it should be listed as an option to open it.
How this policy works is it will read the XML file listed in the path. It turns out that parsing the XML and then applying each registry key in order is a bit slow. The process monitor capture I took earlier can show when it’s accessed. I setup a filter to match the file I was looking for:
I can validate that the ALD script is accurate because each ‘ReadFile’ of the XML file is the start of the default association application loop and the last “CloseFile”.
Explorer.exe also processes the DefaultAppList.xml I have configured, but this is after the desktop is ready so it is not included in ALD but it is visible in process monitor.
Sure enough, setting a RegSetValue filter on the Process ID (PID) what’s happening is it’s writing to the registry one entry at a time:
Is Citrix doing something here to trigger this behaviour or is it Microsoft? As a test I logged onto a Azure Virtual Desktop machine.
When I logged onto a Azure Virtual Desktop published desktop resource, I did not see output for Default File Associations in Analyze Logon Duration:
For launches to a published desktop in Azure Virtual Desktop, Microsoft expects Explorer.exe to apply the policy and Explorer.exe does so after the desktop is loaded so logons are not impeded. But a published resource doesn’t have explorer.exe to apply default associations, how does it operate?
The published app for AVD showed lots of time spent in the Pre-shell phase, but almost no AppX – Load Packages and no Default Associations applied.
Looking at the procmon log for the file type associations being applied and the list was blank!
File associations are not set for Azure Virtual Desktop published applications. So it doesn’t seem to be a behaviour with Microsoft calling Default Associations to be applied during the Citrix logons.
This strongly suggests this behaviour is being caused by Citrix as I don’t have any other options left.
With Default File Associations Policy disabled (or not configured) then Default File Associations are not processed at all for a Citrix logon:
Doing this exercise has uncovered two new logon optimization opportunities. One of those opportunities is a bit frustrating though as it appears Citrix may leverage a feature of Windows (applying Default File Associations) too aggressively causing logon delays. The other appears to resolve AppX Package Load Times entirely. Getting both combined and setup could bring a fair amount of savings to your environment if they are affecting you.
For the File Type Associations application, if you want your users to have file type associations applied to their logons and maintain optimal logon performance, you’ll need to look at applying the FTA’s via a script or some other mechanism. The only utility that I’m aware of to programmatically set FTA’s via command line is SetUserFTA.exe or through a tool like Citrix Workspace Environment Manager (I haven’t tested that to see when it applies though).