I thought it might be useful to outline the approach that I take to designing group policy infrastructure in environments that I manage. Architecting group policy can be a daunting and time consuming task, so it’s good to know how it works before you start. All of what you’re about to read was gathered from Microsoft documentation, and should be accurate to the date of this writing. Everything you’re about to read has been compiled over the last 10 years from a combination of Microsoft best practices and real world experiences tweaking GPOs in production environments.
I use the terms functional and monolithic to describe the two possible approaches:
- Functional GPOs Contain one or more settings from a single policy area and often target a single function (e.g., Browser Security, Workstation Lock)
- Monolithic GPOs Contain a variety of settings from multiple policy areas (e.g., Administrative Templates, security, Group Policy preferences)
The majority of the corporate environments I’ve managed contain Functional GPOs when I start. Most environments should have a mix of both Monolithic and Functional GPOs. This is driven by factors such as the need for delegating certain GPOs to a particular business unit administrator, the desire to manage complexity, and the need to enforce security mandates. A perfect example of a Functional GPO is one that contains domain-wide security policies. In that situation, you might have one Functional GPO that sets those domain-wide policies and can be edited by only one person or group (e.g., the Security Group).
The goal of the Functional GPO is to isolate one or more settings from a single policy area so that they can be handled as a unit and easily delegated to a particular user or group if need be. However, you can go overboard with Functional GPOs. Having a hundred GPOs, each with a single setting, is a tangible example. There are performance penalties to be paid if you have a great number of GPOs.
The goal of a Monolithic GPO is to bundle together a complete configuration scenario within one GPO. Be it the Internet Explorer Security Settings GPO or the Mobile User Configuration GPO, the goal is to keep all settings that relate to the scenario in one manageable and delegated GPO. Monolithic GPOs are ideal for the organizational unit administrator who needs to have control over Group Policy settings for users but shouldn’t be able to create GPOs and apply them to the domain. Monolithic GPOs also ease troubleshooting: Because one GPO is responsible for the lion’s share of policy, you have only one place to look when something goes wrong. As long as the GPOs are well documented, finding and fixing issues is never a problem.
The bottom line is that Functional and Monolithic GPOs both make sense in certain situations, but one might be better than the other from a Group Policy processing-performance perspective. Speaking of processing…
Background vs. Foreground Processing
There are two types of Group Policy processing events: foreground and background. For computers, foreground processing happens on startup. For users, processing happens at logon. Background processing occurs periodically, based on the client’s role. Domain controllers (DCs) perform a background refresh every 5 minutes, whereas client OS versions and regular Windows servers perform a refresh every 90 minutes plus a 30-minute, randomized interval. In addition, Windows Vista and later clients perform a background refresh based on network state. Specifically, if a Windows client (e.g., a roaming laptop) is out of contact with a DC when a background refresh is due, that client immediately performs a background refresh as soon as the DC becomes available. This refresh is often referred to as a network location awareness (NLA) refresh.
Synchronous vs. Asynchronous Processing
Another important aspect of Group Policy processing that has significant performance ramifications is the distinction between synchronous and asynchronous Group Policy processing. To understand synchronous processing, let’s look at a typical example of Group Policy processing from boot-up to user logon.
When a Windows computer starts, there’s a point at which the client connects to the network. At that point, computer-based Group Policy processing kicks off. If this processing is configured to run synchronously, the user doesn’t see the logon dialog box, the Graphical Identification and Authentication (GINA), until the processing is completed. After the user logs on to the system, user-based Group Policy processing begins; the user doesn’t see the desktop until that processing finishes. Thus, synchronous processing elongates the time it takes for a user to boot up the system, log on, and get productive.
Starting with Windows XP, Microsoft set the default for foreground Group Policy processing as asynchronous. This type of processing is also called Fast Logon Optimization and remains the default foreground processing method through Windows 10. Asynchronous processing basically tells Windows to continue doing what it was doing, even if Group Policy processing is still running. So, when a computer boots up, it doesn’t wait for computer-based Group Policy processing to finish before presenting the user with the logon dialog box. Likewise, when the user logs on, there is no waiting on user Group Policy processing before presenting the user with the desktop.
Some Group Policy client-side extensions (i.e., Software Installation, Folder Redirection, Disk Quota, and Group Policy Preferences Drive Mappings) work only when run synchronously. Some administrators essentially disable asynchronous processing to ensure that these policy areas do what they’re supposed to do. These people enable the somewhat-mislabeled Computer Configuration\Policies\Administrative Templates\System\Logon\Always Wait for the network at computer startup and user logon policy setting to force synchronous foreground processing.
The four policy areas that require synchronous foreground processing will signal to Windows to run synchronously the next time foreground system processing occurs, to ensure that they can process their settings. Background processing is, by definition, always asynchronous.
Whether an event is processed in the foreground or the background, no processing occurs if nothing has changed within the GPOs that apply to a given computer or user. In such cases, Group Policy processing goes through the motions of reading all the GPOs that apply. But if, when comparing an existing GPO in AD with its record in the client’s registry of what was done last time, the Group Policy engine notices that no changes have occurred, then each client-side extension that implements that policy area simply “walks away.” Exceptions to this behavior can occur, such as when someone issues a gpupdate /force command from a client.
Here are some types of changes that trigger a full reprocessing of policy:
- Someone makes a change that increments a GPO’s version number. A difference in version numbers between the current, live GPO and the version number that the client last processed is considered a change.
- The list of GPOs that apply to a computer or user has changed. Causes for such a change include changes to security group filters on a GPO, changes to WMI filters that are linked to a GPO, or computer or user security group membership changes that cause a GPO to fall in or out of scope.
Note that even when changes trigger a full refresh of policy, not all client-side extensions completely refresh their settings. Processing should occur in milliseconds in most environments or in a few seconds in the largest environments.
Group Policy Processing Performance
It’s important to think about Group Policy design in the context of having little impact on the user’s desktop experience. To that end, let’s talk about Group Policy behaviors and design decisions that can minimize this impact. First, understand where time is typically spent during Group Policy processing, which is composed of two distinct phases: core processing and client-side extension processing.
During the core processing phase, the user or computer determines which GPOs apply and which client-side extensions must perform work. This phase is also when the Group Policy client determines whether something has changed and whether it needs to take action.
During the client-side extension processing phase, each client-side extension that’s registered on a system and that has work wakes up and process all the GPOs that were identified during the core phase. This second phase is when the actual settings are applied to the client system. In terms of proportion of overall time spent in Group Policy processing, the client-side extension processing phase easily consumes the greatest amount.
This pattern doesn’t change much even when the client is processing many, many GPOs. The time necessary to query AD for GPO information is generally much less than the time spent writing keys to the registry, installing software, mapping drives, and so on. The number of GPOs that you have is less important than what those GPOs are doing. If you have many GPOs that are each doing many things, then your GPO deployment will definitely affect the user’s desktop experience. If you have many GPOs and half of them deploy only one registry policy setting, then the impact will be less. There’s also the question of whether you want to maintain so many GPOs that are doing so little, but that’s a separate consideration.
There’s also the question of how often your GPOs are changing. A ton of GPOs that rarely or never change aren’t going to have much ongoing effect on your users, other than when a change does occur.
Grouping Client-Side Extensions and the Impact on Performance
When you create Monolithic GPOs that contain multiple policy areas, you might be inadvertently increasing Group Policy processing times. Why? The problem has to do with how the Group Policy engine detects a change to a GPO (which ultimately determines whether work must take place). That detection mechanism uses a simple version-number check on the GPO. So any change to a GPO requires that all client-side extensions that are implemented in that GPO must do work at the next processing cycle. Why? Because the Group Policy client has no way of knowing which policy area was changed in the GPO; it knows only that something changed.
Suppose that a computer processes three GPOs: GPO A, GPO B, and GPO C. GPO A and GPO B implement registry and security policy settings. GPO C implements registry policy only. You decide to make a change to security policy on GPO A. The next time Group Policy processing runs, it notices that the version number on GPO A has changed, but it doesn’t know which policy area was changed. So processing must tell the registry and security client-side extensions that they both must process settings. In addition, even though GPO C has only registry policy implemented, the registry client-side extension must perform work, so it must process all GPOs within the computer object’s GPO hierarchy. Processing only GPO A and GPO B would break that processing hierarchy.
Suddenly, a simple change to one policy area in one GPO requires two client-side extensions to perform work across three GPOs. I you have frequently changing policy areas, grouping them together or putting them alone is better than mixing them with policy areas that don’t change much. In the previous example, this approach would equate to moving the security policy areas out of GPO A and GPO B and putting them into their own GPO (or GPOs). If you made a change to one of those areas, only the security client-side extension would need to work, and only against the GPOs that implemented the settings.
Four policy areas (i.e., Software Installation, Folder Redirection, Disk Quota, and Group Policy Preferences Drive Mappings) require synchronous foreground processing. Further, if any of these areas are implemented in a GPO and that GPO changes, then when any of these four client-side extensions process that changed GPO, they tell Windows to run the next foreground-processing cycle synchronously, even if the system is configured to run asynchronous foreground processing. And of course, if synchronous processing is configured, it elongates both machine-startup and user-logon times. Again, proper grouping of policy areas in GPOs comes into play. If a GPO implements Group Policy Preferences Drive Mappings and Registry policy, and you make a change to a Registry policy setting in that GPO, then when the client processes the GPO, it doesn’t know which policy area changed – only that a change happened. So both the registry and Group Policy Preferences Drive Mapping client-side extensions fire up. The Drive Mapping client-side extension tells Windows to run the next foreground cycle synchronously “just in case,” and suddenly an innocent little change to registry policy causes the next reboot or user logon to run slowly. Just as in the previous decision around versioning and grouping of client-side extensions, when you’re implementing one of these four synchronous policy areas, the best practice is to either put them in GPOs of their own or to combine them with each other, separate from policy areas that don’t require synchronous processing.
Group Policy Performance and Loopback
Loopback processing is typically used in kiosk, Remote Desktop Services, or Citrix environments. This type of processing comes in two modes: merge and replace. Merge mode has potential performance effects, depending on where your GPOs are linked in relation to computers that are enabled for loopback. That’s because merge mode first processes user settings for the user object that’s logging on to the loopback computer, then processes user settings that apply to the loopback computer object. This presents an interesting possibility: For example, the same GPO containing logon scripts or other settings can actually process twice, if it’s linked and filtered in such a way that it applies to both user and computer objects. The point here is that if you need or plan to use merge mode, use the Resultant Set of Policy (RSoP) modeling tools that come with Group Policy Management Console to determine what the effect will be on the user. That impact could literally double the time spent processing policy.
Administrative Templates files are divided into language-neutral .admx files and language-specific .adml files for use by Group Policy administrators. The changes that are implemented in these files let administrators configure the same set of policies by using two languages. Since the businesses I’ve worked for have operated only out of english speaking countries, deploying only the English language templates were required. Administrators can configure policies by using the .adml files and the .admx files.
Windows uses a Central Store to store Administrative Templates files. In a domain with a Windows Server 2008 Service Level or higher, the ADM folder is not created in a Group Policy Object (GPO) as it is in earlier versions of Windows. Therefore, Windows domain controllers do not store or replicate redundant copies of .adm files.
Note: If you use a client that is running an earlier version of Windows to change a policy that is created or administered on a Windows 8.1-based or a Windows 10-based computer, the client creates the ADM folder and replicates the files.
Managing the Central Store
To take advantage of the benefits of .admx files, a Central Store must exist in the SYSVOL folder on a Windows domain controller. The Central Store is a file location that is checked by the Group Policy tools. The Group Policy tools use any .admx files that are located in the Central Store. The files that are in the Central Store are later replicated to all domain controllers in the domain.
For At Home, a Central Store has been created for .admx and .adml files. The PolicyDefinitions folder has been created in the following location (for example) on the domain controller:
Copy all files from the PolicyDefinitions folder on a source computer to the PolicyDefinitions folder on the domain controller. The source location can be either of the following:
- The C:\Windows folder on a Windows 8.1-based or Windows 10-based client computer
- The C:\Program Files (x86)\Microsoft Group Policy\client folder if you have downloaded any of the Administrative Templates separately
The PolicyDefinitions folder on the Windows domain controller stores all .admx files and .adml files for all languages that are enabled on the client computer.
The .adml files are stored in a language-specific folder. For example, English (United States) .adml files are stored in a folder that is named “en-US“; Korean .adml files are stored in a folder that is named “ko_KR“; and so on.
If .adml files for additional languages are required, you must copy the folder that contains the .adml files for that language to the Central Store. When you have copied all .admx and .adml files, the PolicyDefinitions folder on the domain controller should contain the .admx files and one or more folders that contain language-specific .adml files.
Note: When you copy the .admx and .adml files from a Windows 10-based computer, verify that the most recent updates to these files are installed. Also, make sure that the most recent Administrative Templates files are replicated. This advice also applies to service packs, as applicable.