Do you want quicker logons in a XenApp AD GPO environment? You do? OK, then…
This has been a subject I’ve wondered about for a while. As I alluded to in my logon times article (which I’ve presented on in further depth a number of times, and will be doing again for the Norwegian user group as a masterclass in June), timely processing of your Group Policies is very important. There are a number of factors that can play into this, such as filters, CSEs, number of settings, etc., but one of the considerations that people sometimes forget about is synchronous versus asynchronous processing mode.
What are these processing modes?
Put simply, the user’s Group Policy (which are applied when they log on to the machine) can be applied one-by-one (synchronously) or all together (asynchronously). Obviously, an asynchronous process is better. However, depending on the user configuration and the Group Policies in use, sometimes the synchronous process is unavoidably required. We will try to offer some insight in this article as to how you can try to invoke the asynchronous mode where possible.
Understanding GPO processing behaviour
Group Policy settings are grouped into categories (Admin Templates, Security, Folder Redirection, Software Installation, Group Policy Preferences, etc.) Each category has a specific CSE (client-side extension) to process them, and each CSE has its own rules for doing the processing. Group Policy Preferences (GPP) are actually a set of client-side extensions, not a single one, so different “flavours” of GPP may have different CSEs and therefore different rules.
Now, if you read the Microsoft documentation at this link, you’d be forgiven for thinking that the differences between asynchronous and synchronous processing is to do with threads, because that’s what it says “asynchronous processing…can occur on different threads simultaneously”. That’s incorrect, though. With a hat-tip to Darren Mar-Elia of GPO MVP fame, asynchronous versus synchronous processing has nothing to do with threads. CSEs always process on different threads.
The main difference is in how quickly things are presented to the user. With synchronous versus asynchronous computer GPO processing, the computer does not wait for the network to become available before presenting the sign-in to the user, in asynchronous mode. So if you boot machines and they process their GPOs in asynchronous mode, the boot time to sign-in is faster.
User processing is the key area, though, especially for our logon time KPIs. With asynchronous user policy processing, when a user logs in, the desktop can be displayed before Group Policy processing is actually finished. An easy way to tell if you are in asynchronous processing mode is if, during logon, the system DOES NOT display the feedback items as to what is being done, such as “Applying Group Policy Registry policy” (see image below for an example). These updates will only be shown if the user’s logon is being done in synchronous processing mode. So if you’re in asynchronous user processing mode, you should usually get quicker logons.
It is also important to understand the concept of “foreground” and “background” processing. Foreground processing occurs when the user logs in (or when a device is starting up or shutting down). Background processing occurs when a Group Policy refresh is initiated, either during the user session or when a device is idle, whether this is automatically in the refresh cycle, or manually launched by a user or admin from the command line or GPMC. Background processing is ALWAYS asynchronous, whereas foreground processing can be either synchronous or asynchronous.
Some CSEs require synchronous processing, whereas others do not. If foreground processing is being performed, and there is a CSE that requires synchronous processing, then all settings will be handled synchronously. If foreground processing is being performed and no CSEs require synchronous mode, then asynchronous mode will be used.
During background processing (i.e. during a Group Policy refresh or update), everything is run in asynchronous mode. However, if there are CSEs that require synchronous processing, they will be checked.
If the CSE has a Registry value set in HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\[GUID] (where [GUID] is the identifier referring to the CSE in question) that is called NoBackgroundPolicy and has a value of 1, the CSE will not be called during background processing.
However, if this Registry value is NOT set to 1, then the CSE that requires synchronous processing WILL be called. However, as background processing always runs asynchronously, it will not be run. What happens instead is that the CSE will make a request that the next logon (or startup, if they are computer policies) will be run in synchronous mode rather than asynchronous. It makes this request by setting the Registry value(s) below, HKLM for Computer-level policies, and HKCU for User-level policies:-
In these keys, the CSE will set a value of ForceRefreshFG to 1 to invoke synchronous processing at the next startup/logon.
Obviously, the question is – which CSEs require synchronous processing, and which ones of these will set the ForceRefreshFG when they are called during background processing?
The following CSEs require synchronous processing – Folder Redirection and Software Installation Policies. (Disk Quotas also used to require this, but they’re not even available any more AFAIK, let alone used) Group Policy Preference Drive Maps, since Windows 8, now no longer require a synchronous refresh to process. So unless you are using a Windows version earlier than 8, you can use GPP Drive Maps with impunity – if you are on an earlier version, then you will have to avoid using it if you want asynchronous processing.
Why asynchronous processing?
Naturally, the question is “what benefit would this give me?” Back to my earlier article about logon times, improving such KPIs can have a number of benefits. Improving user Group Policy processing can make your logons quicker (a lot quicker, if you have complicated GPOs and lots of CSEs), which in turn leads to better user satisfaction, increased productivity, money saved, better security, employee retentions, positive image for the IT department – a whole raft of benefits. Improving the user experience by a significant amount, which this can achieve, is always a tangible plus.
Enabling asynchronous processing
In order to make sure that asynchronous processing is available, you need to set the following Group Policies:-
Computer Config | Admin Templates | System | Logon | Always wait for the network at computer startup and logon – Disabled
(additionally for RDSH servers)
Computer Config | Admin Templates | System | Group Policy | Allow asynchronous user Group Policy processing when logging on through Remote Desktop Services – Enabled
Once these are set, asynchronous user processing will be enabled at logon when possible.
Note that if you are running a SERVER operating system, logons will always be synchronous UNLESS you have installed the Remote Desktop Session Host role and set the GPOs above. Asynchronous user GPO processing is activated only when a server is an RDSH system and has the policy set correctly. This is bad news for those of us (me included!) currently using the XenDesktop VDA install with the /SERVERVDI switch to give ourselves Server 2016 or 2019 instances in dedicated one-to-one VDI mode (a la Amazon Workspaces) – all of your logons will be in synchronous mode 🙁
Now, you may have noticed that in the GPO description it says that synchronous processing will ALWAYS be used if the user has a home drive, roaming profile path, RDSH home folder, RDSH profile path or logon script defined on the user object in AD, or if the user has never logged onto the computer before. In my testing, this isn’t strictly accurate. The one condition mentioned here that does, definitely, force synchronous mode, is the last one – whether the user has logged on to the computer before.
The fact that a user has logged on to a system before is measured not in the ways I thought it would be. Firstly I thought it would be indicated by cached credentials, but it’s not. I then thought it might be driven by the presence of a local profile, but that’s not it either (thankfully!) It’s actually done by Registry values.
Key – HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\State
Value – NextRefreshMode REG_DWORD 2
Value – NextRefreshReason REG_DWORD 0
If you set these two values within your default user profile, then the system will believe a “new” user has already logged on to the machine, and will use asynchronous processing mode. You can set these values within a custom default user profile such as I’ve blogged about previously, or you can simply edit the default profile directly in your image by following the steps below.
- Open regedit on the system where you are editing the default profile
- Highlight the HKEY_USERS hive
- Click on File | Load Hive
- Browse to c:\users\default and select the ntuser.dat file (you may need to Show Hidden Items and Protected Operating System Files in Explorer to see it)
- Give it a name (e.g. default)
- Open up the hive with the name you gave it above
- Browse to the registry key HKCU\Software\Microsoft\Windows\CurrentVersion
- Create a key called Group Policy
- Create a key underneath this one called State
- Create the two REG_DWORD values with the names and data specified earlier
- Highlight the root of the key you loaded with the custom name
- Click on File | Unload Hive and then click Yes (do not forget this step, otherwise you will lock the default profile in memory!)
- Delete any log files with extensions of .LOG*, .BLF and .REGTRANS-MS
This will mean you have inserted the required Registry values and now all users that create new profiles using that default profile will be processed in asynchronous mode.
Unfortunate update 03/03/2022 – it now seems as if the above Registry key has moved to a different area of the system. Instead of being based in HKCU, the values that drive the “I’ve logged on previously” setting are now held in HKLM. Precisely, you need the following values
- HKLM\Software\Microsoft\Windows\CurrentVersion\Group Policy\State\[USERSID]
- NextRefreshReason DWORD 0
- NextRefreshMode DWORD 2
Can you spot the issue yet? Yep, because these are based in HKLM, they are nigh on impossible to roam or create ahead of time (and the fact that they are in a user-specific subkey makes it even more annoying). In order for asynchronous policy processing to now be enabled, these values need to exist on the endpoint prior to user logon. These values are read extremely early in the logon process (so early that even Ivanti can’t inject them in enough time to make a difference), and using logon scripts, scheduled tasks, FSLogix redirection or any other trickery doesn’t seem to be able to force the issue.
Also, when a user’s profile is removed or when a profile management tool (like FSLogix or UPM) is logged out, these HKLM keys are deleted from the machine, meaning that every logon will be synchronous. The only possible way I can see to force asynchronous mode in a non-persistent environment is for you to create the above set of keys on your endpoints for every single user in your estate. Given that some of us have hundreds, thousands, even hundreds of thousands of users, I can’t see that flying, although if you wanted to do it, it will work.
Hope springs eternal though, because there was a specific version of FSLogix – 2.9.7349.30108 – that actually managed the roaming of these settings, capturing the settings into .reg files the same way it does with the HKLM ProfileList keys that are also part of the user profile. Because FSLogix can intercept and inject very early in the logon (because it has to, obviously), then these settings can be presented to the operating system in time to trigger asynchronous processing. See below for how it captures the HKLM Registry settings into the profile.
So if FSLogix (and/or other vendors) could do this before, then they can certainly do it again. But unfortunately, in the meantime, if you want asynchronous processing you either need to create the user’s SID key in HKLM and populate it with the two values prior to logon, or you need to use FSLogix version 2.9.7349.30108.
Much respect due to my Australian alter ego James Kindon for doing most of the hard yards on this – and I guess it’s now up to FSLogix/Microsoft to bring this much-needed functionality back.
User object settings
Now, I’ve tested all the possible configurations of AD user object settings and I can report that as long as you have the Registry values in your profile set as above, NONE of these settings will force you to use synchronous mode. What they WILL do is ensure that the network is fully initialized before the user is allowed to log on (because they need to get on to the network to find home drives / logon scripts / roaming profiles), but that means that the Computer processing will be performed synchronously, not the user processing.
For posterity, all of these settings will not affect the mode of user policy processing:-
- A home folder specified in the Profile tab
- A logon script specified in the Profile tab
- A roaming or mandatory profile path specified in the Profile tab
- A home folder specified in the Remote Desktop Services Profile tab
- A roaming or mandatory profile path specified in the Remote Desktop Services Profile tab
If you do use logon scripts (and there are better ways to do things these days, trust me), then make sure that the GPO that forces logon scripts to run synchronously is not set, found at Computer Config | Admin Templates | System | Scripts and User Config | Admin Templates | System | Scripts. Also, remember that 2012 upwards logon scripts don’t execute at logon anyway, unless you set the GPO that enables it.
An interesting discovery at this point was that a home folder specified on the Remote Desktop Services Profile tab on the user object would not map unless the following Registry value was present:
HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\fQueryUserConfigFromDC (REG_DWORD, value 1)
This is quite odd because the Policies key would indicate this is a GPO setting, but I couldn’t find any reference to the setting in Microsoft’s GPO documentation. Anyway, if you find an RDSH Profile home folder won’t map despite being defined on the user, check that this key is present and it should solve your issue by putting it in.
Group Policy Preferences Drive Maps
As mentioned earlier, I’ve also tested these and they don’t force a change to the processing mode, even when changes are made to the settings, so you can use these without impact, and Microsoft’s documentation needs updating.
if you’re using a Windows version prior to 8 or 2012 though, then GPP Drive Maps will force a synchronous refresh. In this case, you need to find a better (!) way to map drives. WEM, or, God forbid, a logon script would have to be your choice, or something like Ivanti UWM. Alternatively, you could just use my ideas and forget about drive mappings altogether 🙂
Software Installation Policies
If you’ve got Software Installation Policies, then these will force a change to synchronous mode to apply. But the question is – who still uses Software Installation Policies??? Everyone has better ways to deploy software these days – DON’T USE THIS METHOD!
Now, the other thing that will, from a user perspective, force a change to synchronous mode is Folder Redirection. I’ve run the tests and it is indeed true – if you log on with Folder Redirection GPOs set, it goes to synchronous mode, and if you pick up a Folder Redirection GPO whilst doing a background refresh, the next logon will be a synchronous one.
Now if you’ve read my article about Folder Redirection you will know that I recommend only doing it for certain things and in certain ways, but you will also remember that Folder Redirection is (mainly) initiated by setting a Registry value. If you don’t use the GPO CSE to do it, and simply set the Registry value by Group Policy Preferences, then you can have the Folder Redirection applied without falling back to synchronous processing.
Now, there are certain caveats to this – if you use the Folder Redirection in this way, you won’t get any of the “options” that you can access when you use the CSE version (shown below)
To be honest, I don’t use a lot of these options, and I certainly don’t get involved with moving data around much from non-redirected areas to redirected, so as far as I am concerned, using the Registry method to redirect folders is definitely a viable option. Your mileage may vary, but if you want Folder Redirection and asynchronous processing, this is the way to achieve it.
Citrix User Profile Management
A couple of notes for UPM users. Firstly, if you’re using a UPM template profile you will need to add the Registry values that I specified earlier in the same way you would do a default profile, so that the profile “appears” to have already been logged on.
Secondly, don’t use the user home drive for the Citrix UPM profile path. This appears to call synchronous mode, so try and use a UNC path with #SAMAccountName# or %USERNAME% instead and you should be golden.
Finally, if you use the Citrix UPM Policies to enable Folder Redirection, this uses the Microsoft GPO method, it doesn’t just manipulate the Registry. So if you configure Folder Redirection through UPM policies, you are enabling a requirement for synchronous mode (thanks to Martin Zugec for the confirmation!)
So – how much difference does this actually make? In order to see if you’re using synchronous or asynchronous processing, the event log is your friend. Open Applications and Services Logs | Microsoft | Windows | Group Policy | Operational and filter the log by event id 5340. Every processing of Group Policy will show the mode used.
We are going to choose a device in an OU with lots of user GPOs to see how much difference this makes for logon times. Obviously, if you don’t have many user-level GPOs, then the amount of time you can save will not be very much, but in my experience many enterprises often deploy quite an amount of user settings. I’ve linked about 15 user GPOs with one or two settings each. I know my logon times article said you should use bigger GPOs with more settings per policy object, but in the lab I find it much easier to troubleshoot with smaller GPOs.
Now the one caveat around using asynchronous processing as much as possible is that policy processing may not actually be finished by the time the user’s desktop is presented. In most cases and in my testing this doesn’t appear to be an issue at all – I didn’t notice any policies that hadn’t applied or were not done in time for the user interaction to begin. But the point I am making is that if you make this change you need to thoroughly test that all the policies are correctly applied for your users.
I logged my test user, which had never logged on to the XenApp server before, ten times in succession for “synchronous” mode, then I applied the GPO to enable asynchronous mode, and logged it on ten times in succession again, after deleting the profile. So the first logon in each set of timings is longer because it is creating a new profile, all of the other timings the user already has a profile (saved into Citrix UPM in this case, but it doesn’t matter how you persist it, for purposes of this demonstration).
In synchronous mode:
- Logon 1 – 36.48 seconds
- Logon 2 – 10.94 seconds
- Logon 3 – 10.72 seconds
- Logon 4 – 10.95 seconds
- Logon 5 – 11.21 seconds
- Logon 6 – 12.12 seconds
- Logon 7 – 11.06 seconds
- Logon 8 – 10.80 seconds
- Logon 9 – 12.01 seconds
- Logon 10 – 11.97 seconds
Now for asynchronous mode:-
- Logon 1 – 23.81 seconds
- Logon 2 – 4.40 seconds
- Logon3 – 3.07 seconds
- Logon 4 – 2.55 seconds
- Logon 5 – 5.67 seconds
- Logon 6 – 4.11 seconds
- Logon 7 – 3.39 seconds
- Logon 8 – 5.21 seconds
- Logon 9 – 2.89 seconds
- Logon 10 – 4.05 seconds
So there you have it – a marked increase in the efficiency of the logon KPI. I was actually quite worried after the first set of tests because I thought my initial performance was very good, but luckily, it got better 🙂
So the conclusion is, if you combine forcing asynchronous mode with the logon optimizations I recommended in my original article, you can make your logons even better – assuming that you’re making use of user Group Policy to a reasonable extent.
So, to enable asynchronous processing of user GPOs at logon, you need to do the following:-
- Ensure your default profile or template profile has the Registry values added at HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\State for NextRefreshMode and NextRefreshReason
- Ensure that the GPOs are set to allow asynchronous processing (one policy on clients, two on RDSH servers)
- On a server OS, make sure the RDSH role is installed, otherwise every logon will be synchronous
- If you need Folder Redirection policies, use Group Policy Preferences Registry Items to set the UserShellFolders values directly, rather than using GPO CSEs. Note for some folders (like Downloads) you may need to look up the GUID reference. Easiest way to do this is actually configure the redirection policy through the CSE, and then check the Registry to see what the GUID name is, then set it up as a GPP instead.
- If you must use logon scripts, ensure that the Group Policy Object for “Run logon scripts synchronously” is not set
- NEVER use Software Installation Policies via GPO, if you can at all avoid them
- Don’t worry about defining home folders, profile paths and logon scripts on the user object – this doesn’t affect processing, in my testing (although bear in mind I did all of it on Server 2016 and Windows 10)
- If you’re using UPM, don’t use the home drive as part of the user profile path
- If you do need to use synchronous CSEs, update them as little as possible
- Group Policy Preference Drive Maps won’t cause a problem unless you’re on an older (pre Win-8/2012) OS. If you are on the older versions, find a better way to deal with mapped drives
- Interestingly, Group Policy Preferences has an Item-Level Targeting that allows you to apply items dependent on what the GPO processing mode is. So if you had a particularly convoluted or time-consuming GPO, you could set it to only be applied if the user was in asynchronous mode, if you so wished.
- Test thoroughly and make sure all expected policies and config items are present!
If you can get most user logons running in asynchronous mode, this should allow your logons to be streamlined even further, which is a win for everyone.