Group Policy Objects: How To Define and Manage Them Properly
Group Policy Objects have been an intrinsic part of any Active Directory deployment since they came along with Windows 2000. But given that they have been around for such a long time, it is common to find GPO implementations that are not in the best state of repair. In this article, we will cover some quick and easy ways to try and get back on top of them.
Active Directory and Group Policy Objects replaced the antiquated Windows NT4 and its “flat” directory services. At the time I was working with a client who had managed to increase the size of their NT4 SAM (Security Accounts Manager) database to over 100MB – a limit Microsoft assured us was impossible. This borderline use case meant that they (and hence I) was one of the early adopters of full Active Directory services. Prior to this, I had been using batch files (yes really!) to emulate the functionality that Group Policy eventually provided – running scripts overnight that reset key NT4 domain user group memberships, user rights assignments, and the like.
Prior to Group Policy – using command scripts to push the limits of NT4
With such an approach having been used previously, having Group Policy Objects come along was a blessed relief. Over the years, Group Policy developed quite strongly, although the core Group Policy engine hasn’t had an update now since 2006.
Group Policy Objects are settings that can be applied at domain, site, OU or device level, and push User or Computer configuration items onto the objects in AD. Computer Config items are applied at boot, User Config items at user logon, and they are both periodically refreshed in the background. You can use the Microsoft-provided settings and also adopt those provided from third-party vendors to manage their own configuration areas. Microsoft are still producing new ADMX and ADML files for their newest operating systems and applications, but there are competing controllers such as InTune and Desired State Configuration (DSC) arriving that may, eventually, replace the venerable GPO method. However, given that GPOs are intertwined into most enterprise environments the world over, it is unlikely that we will see the end of them anytime soon.
Group Policy feels quite monolithic, but it is more of a framework at heart. Microsoft provide the engine and their built-in set of modules, and other vendors add their own. These modules are not actually called modules – Microsoft refer to them as client-side extensions, or CSEs. The CSEs are found in DLLs registered in the Registry key:
A list of client side extensions
CSEs are processed (whether at boot, logon, or refresh) in a particular order. The Administrative Templates CSE goes first, followed by everything else in the numeric order of the GUID from the Registry. The list below shows the CSEs in order of processing. Don’t think you can prioritise a particular CSE by changing the GUID – that simply breaks everything.
CSE processing order
For each CSE the underlying DLL has to be loaded and initialised. Group Policy Preferences Shortcuts, Ini Files and Environment Variables are the CSEs that take the longest to load, so be careful with these ones.
Setting up GPOs
When setting up your Group Policy Objects, admins are often faced with the choice between having “one setting per GPO” or “one GPO with many settings defined”.
Using the “one setting per GPO” method makes troubleshooting a lot easier (as you can see in the screenshot below). If there is a problem with something, you can disable the GPOs one by one until you locate the problem.
One setting per GPO
However, this is an inefficient way of processing Group Policy Objects. Group Policy settings are stored on the domain controllers in one file per CSE and GPO. If a CSE’s settings are spread across multiple GPOs, the number of files that have to be fetched during processing increases. This can have an adverse effect, particularly if your client is talking to a domain controller over a slow link.
So the best thing to do is make sure that each GPO you configure contains all of the settings from a particular CSE (see example below).
One CSE per GPO
Naturally, this makes troubleshooting more difficult – the Administrative Templates CSE contains a HUGE amount of items! To get around this, I often use the “one setting per GPO” approach simply for development and test environments (where more troubleshooting is done), and adopt the “one GPO with many settings defined” approach in production.
Another common misconception I see with GPOs is that people will change the GPO Status in the belief it makes processing more efficient. If a GPO has, for instance, only Computer Config settings within it, they will disable the User Config items in the dialog shown below.
GPO Status option
Unfortunately, this gives no benefit whatsoever. The GPO has to be read and loaded before it understands that part of it is to be ignored, so don’t fall in the trap of studiously changing these where you think it is needed (I have done in the past). The main point of this function is possibly to aid troubleshooting when you have large GPOs with many settings (which, if you are following my advice, you should have).
Loopback is one of my favourite interview questions, because it is so tricky to define. The loopback processing GPO setting allows you to apply user configuration items in a computer context. So if you want to apply a different user setting based on the device the user logs on to (for instance, maybe a different desktop background when logging on to an RDSH server rather than a desktop), you use loopback to configure those user settings in the machine context.
You can apply loopback in two modes – Replace, or Merge. In replace mode, when the user logs into a computer enabled for loopback, instead of getting the user policy settings they would normally by virtue of their user account’s location in AD, they get user settings in GPOs that apply to the computer object. In merge mode, when the user logs into a computer enabled for loopback, they first process their “normal” user settings for their user account, then they process any user settings in GPOs that apply to the computer object. If there are conflicts, then the computer-object-linked GPO user settings override the user’s normal settings, while logged into that computer.
If Merge mode is enabled, this essentially creates two “passes” of Group Policy application and will therefore take longer to process. I normally recommend using Replace mode wherever possible.
Filtering is crucial to GPO processing, as this allows you to target GPOs in a more granular way. However, there can be overheads associated with them. There are three methods of filtering you can use.
Security filtering is done directly by NTFS permissions on the GPO files themselves. They are processed very quickly because the user or computer can simply either see them or not. When configuring security filtering for user configuration items, remember that part of the processing is done in the computer context, so you need to add your target users/groups AND the Domain Computers group into the security filter.
WMI filters allow you to target anything you can map out to a Windows Management Instrumentation query. Most of these are fairly efficient, but some (such as LDAP or product queries) are particularly adverse from a processing perspective. I try to avoid the use of WMI filters where possible.
Finally, Group Policy Preferences allows you to use an additional filtering level called Item-Level Targeting. This is extremely granular, allowing you to filter based on a huge amount of parameters. However, some of them have an associated overhead, particularly OU, LDAP, domain or site queries. Again, from both a management complexity and efficiency perspective, I try to avoid using ILT filtering unless absolutely necessary.
Item Level Targeting
Computer or User Config items
In some cases, I see certain GPOs (a good example is Disable AutoPlay) being applied as User Configuration items but applied to every user in the domain. What people fail to realise is that a lot of settings (such as Disable AutoPlay) actually have a Computer Configuration item as well. So if a setting is being applied globally, why not use the Computer Config item rather than the User Config item and save the processing time for each user?
Computer or User Config?
You can apply this to Registry items as well (often settings you apply in HKCU will apply equally well when used in HKLM), and even some GPOs that do not officially have computer configuration items will actually respect the policy paths if they are lifted and shifted from HKCU to HKLM! With this in mind, let me take this moment to say every GPO admin should have a copy of Microsoft’s GPO settings spreadsheet (this is where you find the Registry keys that each policy applies to).
Design of your GPO structure is key, but difficult to get perfect. Especially if you are like me and try to restrict your filtering to Security only, it can be exceptionally challenging.
GPO architecture obviously follows the setup of your Active Directory Organizational Units (OUs), as most people apply policies at OU levels (I occasionally see a few settings applied at site or domain level, but
nothing large). There is no particular set approach recommended to OU architecture, but there are two common ways of setting it out – “flat”, or “nested”.
The flat approach puts all user and computer objects into high-level OUs, applies large sets of GPOs to these OUs, and then uses filters to apply them to their targets.
The nested approach uses deep nesting of OUs to divide user and computer objects into specific areas, and then applies GPOs to each OU as required.
As you can probably guess, I always adopt the nested approach where possible, because this allows us to minimise the use of filtering and give a logical structure to the layout of the organisation. In an ideal world, a nested approach with security filtering only would be the best way to structure your Group Policy implementation.
A nested OU structure
There are features such as “Enforced” and “Block inheritance” that allow you to either force GPO application down OU structures or alternatively stop them from being propagated. In many environments, I see Block Inheritance used where they have tried to start afresh with their GPO implementation and don’t want any of their “old” GPOs affecting a new environment – only for the same problems to arise in the “blocked” area years later. Given the effect that enforcement and blocking have, again, in an ideal world I would prefer not to see them used at all.
A huge problem I see with GPOs is that they are never reviewed on an ongoing basis. I have lost track of the number of enterprises I have worked in where GPOs are still being applied that only work on Windows XP and Server 2003! Don’t forget, the GPO engine isn’t clever enough to skip past an OS if the settings don’t apply – it will still write them to the Registry, just the operating system will ignore them.
An ongoing review should be done to remove all unlinked, deprecated or inapplicable GPOs from OUs that have them linked. There are PowerShell scripts available that can help with this. Anything that no longer applies should be link disabled and then deleted later on.
Another important point to make is that in many environments, lots of administrators have access to change GPOs. This can result in chaos when a setting is changed or removed erroneously, potentially affecting huge swathes of the user base. However, what many people don’t realise is that Microsoft have a tool called Advanced Group Policy Management (AGPM) that allows you to change control GPOs in a more organised fashion. The GPOs can be checked in, checked out, locked and restricted. This tool is completely free and should be used in every environment where there are big groups of administrators with access to Active Directory.
So hopefully this is a quick guide to performing some optimisation of your GPO and AD structure to improve both management and processing. There are many other aspects to GPOs which it is impossible to dive into in a single article – such as drive mappings, folder redirections, asynchronous processing, logon scripts, etc. – but hopefully we may cover some of these in follow-up pieces.