
Way back in 2025, I posted the first installment of my AD Tips, Tricks, and Facts series. That article covered OU structures (read it here if you missed it). While I did touch on Group Policies in that post, mostly covered ‘No Override’ and ‘Block Inheritance’ settings. In this article, I plan to go deeper down the old GPO rabbit hole.
Group Policy Overview
On the off chance that you are not familiar with Group Policy, I’ll start off with some high-level info.
Group Policy is a method for applying mandatory and optional configuration settings to computers. You can apply those settings from a system or a user perspective. Group Policy Objects (GPO) consist of collections of Administrative Templates. These policies can be configured and then deployed to achieve a desired state for target users and systems. Administrative Templates are essentially a set of graphical elements, explanations, and options that show up when you edit a GPO.
Behind the scenes, there are four types of settings that can be applied via GPO. These are Security, Permanent, Temporary, and Preferences. I’ll give a brief overview of each before we dig in. There is technically a fifth type, if you count Software Settings, but these are a bad business. I don’t plan to go into these in this post.
Security Settings
These are the settings that you would see under Policies -> Windows Settings -> Security Settings. These values can generally also be set using the secedit functionality built into Windows. I would avoid leveraging the secedit utility unless you have fully disconnected systems requiring hardening. Even then, I would suggest using a third-party product for this purpose. There are a number out there that can take a GPO and apply it to an offline system instead. That way, policies can be at least somewhat centrally managed and a degree of enforcement can also be assured.
A key thing to keep in mind is that these settings are among the most dangerous to configure. Depending on where the policy is linked (or isn’t linked), you could prevent key system functionality. In one case, I encountered an environment where someone had removed all of the default rights assignments in the Default Domain Policy (DDP). This locked them out of…well…everything. Fortunately they still had an active login on a DC. This enabled me to reset the DDP to defaults and recover the environment with dcgpofix. The settings in this section are nearly entirely what I call ‘Red Dot’ settings. This is a term I picked up from Darren Mar-Elia (also known at one time as ‘The GPO Guy’). I’ll get to the whole ‘red vs. blue’ thing soon, but not just yet.
An item of note related to these settings is the Password Policy values. I see people setting these in various policies all the time, however these values only take effect in two scenarios. If you configure these settings on the local device, you can impact any locally created accounts for a stand-alone (i.e., non-domain joined) computer. If the computer is a member of a domain, these settings are ignored unless linked to the domain root. Putting these settings into policies linked anywhere else is a waste of effort, as these settings will be ignored.
Permanent
Just like Security Settings, these are ‘Red Dot’ settings. ‘Red Dot’ applies to any settings that are ‘tattooed’ on the registry. Once a policy sets one of these values, they must be intentionally changed back to the original value. Simply removing the policy, or setting it to nothing, won’t cut it. In the old days, Administrative Templates from third parties often set permanent values. Fortunately, most providers have since updated their software to correctly process ‘Blue Dot’ settings, along with updating their templates. Knowing which of your configured settings fall into this category early on can save you endless hours of troubleshooting.
Temporary
Almost all settings configured by Administrative Templates are known as ‘Blue Dot’. This means that all it takes to revert to the original behavior is removing the setting. Once this type of setting is no longer part of the scope, the system returns to the default behavior. Depending on the setting, won’t revert until either the service, or the system, have been rebooted (see my sub-note below).
As a sub-note on reboots, it can sometimes take several before a setting is actually updated. This has to do with the way that systems process policies. If you change an existing policy, then a simple gpupdate and maybe a single reboot should set things as intended. If you move a system, or modify a setting only checked on boot, things are more complicated. For a move, the first reboot just lets the system realize it’s in a new OU. You would still need another gpupdate to pull new policies, then another reboot to apply all the settings. On occasion, I’ve needed as many as three reboots to make those values effective. This is only for those in a hurry though. The system will eventually see all the changes on it’s own, so waiting a couple hours and then rebooting is usually enough.
Whether a given setting is ‘Blue’ or ‘Red Dot’ can be determined by looking at the registry path configured by the setting. If the path contains ‘Policies’, then the setting is Blue Dot. If the path does not contain ‘Policies’, or isn’t a registry setting, then it’s a Red Dot setting. The exception to this would be Policy Preferences configured in a specific manner.
So, do you have to tear apart the ADMX files to find out which registry paths are being set? I mean…you could, but you could also perhaps just download the handy Group Policy Settings Reference spreadsheet from Microsoft. You can access the Windows 11 2025 (25H2) version of the spreadsheet here. There is no separate spreadsheet for servers, as the same policy values should be used for both servers and workstations. Once upon a time there were differences, and a few settings are functionally server only. Microsoft normalized the OS code between the two some time back and this became a non-issue.
Preferences
These settings are found, handily enough, under the ‘Preferences’ sections of the GPO editor. That said, they are a bit of a different beast. Policy Preferences were originally part of a separate third-party software product called PolicyMaker. Microsoft bought the company in 2006, and integrated the functionality as part of Server 2008. Unlike regular policy settings, Policy Preferences use ‘Client Side Extensions’ (CSE) to process the values in the policy. It’s these CSEs that make updates to the system. Since these values are processed differently, that also means that they have their own logs and ways of working.
Policy Preferences are technically Red, Blue, and Other, depending on how you configure them. Preference settings are functionally Red Dot by default, even when not setting a registry value. If you access the ‘Common’ tab though, you will see two options that can affect this behavior.
The ‘Apply once and do not reapply’ checkbox configures the setting only on the first application. If the user then modifies the value, this won’t be overridden by the defined Preference on refresh. If you later update the setting though, it gets detected and ‘new’ and gets reapplied.
The ‘Remove this item when it is no longer applied’ checkbox causes the system to remember the original value. When this option is applied, it restores the original value when the policy is removed. This is similar to the functionality of Blue Dot settings, though the actual mechanism differs.
Policy Refreshes
Group Policy is automatically refreshed on systems every 90 minutes, plus or minus a random 1 – 30 minute buffer. This ensures that systems don’t overwhelm the DCs by all trying to pull down new policies at the same time. The exception to this is the DCs themselves, for which the policies are functionally ‘local’. DCs reapply their policies every 5 minutes, just like local policies on all other systems.
When clients refresh, they perform a number of steps, which I won’t cover in detail. The important part of our purposes, is that policies are cached on the local system. When it comes time to refresh, they check for an update indicator and, if none, or the domain is not available, they refresh from cache. If you find yourself scratching your head on why a refresh would still occur if there were no changes, I will explain…no, I will sum up.
When a client refreshes, it functionally deletes everything under the Policies keys in the registry. It then recreates them for all the ADMX values from either their cache. This allows the system to skip settings comparisons and just force everything to desired state. Policy Preferences do verify the individual settings against the defined policy, unless the setting is configured to only apply once.
General Best Practices
Okay, now that the basics are out of the way, lets talk about what I consider to be ‘best practices’. This list is not intended to be exhaustive, as there are a great many resources out there with excellent guidance. This list is my list of things that I see time and again. I often end up having to fix these issues, so that’s why I’m writing about them. That said, a few of these may seem familiar, so stick with me.
| Don’t 🗷 | Do Instead 🗹 | Why ❓ |
|---|---|---|
| Use ‘No Override’ or ‘Block Inheritance’ to control policy application | Adjust OU structure to align with administrative instead of visual needs and use layered policies OR leverage advanced delegation to control ‘Apply group policy’ right for policy | Creates administrative blind spots, increasing troubleshooting complexity, difficult to effectively manage |
| Remove ‘Authenticated Users’ from delegation or remove ‘Read’ access for ‘Authenticated Users’ in advanced delegation settings | Use advanced delegation to remove the ‘Apply group policy’ for ‘Authenticated Users’, then add the desired group containing users or systems | Slows down policy processing on endpoints as they know the policy exist, but cannot access them, so must wait for timeout instead |
| Create local accounts, particularly Admin accounts, using Policy Preferences | Add common local accounts to your image and then use Windows LAPS to dynamically differentiate and manage the passwords | Passwords are not encrypted or encoded within policy preferences and can easily be dumped |
| Repeat the same settings in every policy | Use a layered OU structure, along with dedicated policies at each level, in conjunction with a layered approach (enterprise-wide at the top, more specific values lower, overrides at bottom OU); only incorporate the minimum required values and ensure regular review | Easier troubleshooting of issues, more consistent results, and reduced processing overhead for clients |
| Assign scripts to users or systems | Nearly anything that can be accomplished in a script can also be accomplished using Policy Preferences | Policy level scripts, particularly when stored inside policy, are challenging to keep track of and rarely see updates, in addition to being less visible overall; Policy Preferences have better targeting options, more controls, less knowledge required, GUI |
| Link a single policy to dozens of OUs | Use a layered OU structure, along with dedicated policies at each level, in conjunction with a layered approach (enterprise-wide at the top, more specific values lower, overrides at bottom OU); Each policy should be specific to a single OU path | Far easier to apply and enforce enterprise level controls and structured overrides that are far easier to locate and verify |
| Attempt to distribute or install software using GPO | Use software distribution tools such as SCCM or Intune to deploy all software packages | Deployment via GPO is slow at best and more often unreliable; Increases size of the SYSVOL and requires high levels of privilege to make updates, so new installs require increasing numbers of updates as package is not easily maintained |
| Modify the contents or links for the Default Domain or Default Domain Controller GPOs | Create a new policy to hold enterprise-specific settings that must be applied at the root or Domain Controllers OU, and place all custom settings there | Easier recovery in the event of an issue (just unlink); reduced risk overall |
| Deploy GPOs with both User and Computer settings in the same policy | Deploy dedicated policies for User and Computer settings, with the opposing elements disabled (i.e., Computer policy with User settings disabled and vice versa) | Reduces processing overhead for endpoints, since user and system level policies are processed at different stages and every policy setting must be assessed for applicability |
| Link lots of policies to the domain root or inflate a single root policy with tons of settings | Limit root policy settings to baseline User Rights Assignments, Audit settings, and Password Policy; Ensure your OU structure is deployed for administrative, rather than visual needs (OUs for delegation of permission and segregation of policy settings, not Win10, Win11, etc. OUs); Create a distinct GPO for each root level OU; Create ‘holding OUs’ to replace the default Users and Computers containers, then run redircmp and redirusr to change the default locations | You will at some point have to override values, so having this split early on reduces overhead later and makes things more flexible; Splitting out content, even if it’s the same settings for every root OU initially, reduces the risk of a single change impacting the entire domain; Changing the default locations from containers to OUs enables application of policy (even if you don’t “use” these containers, things may still end up there); Note: Do not remove existing default objects from the default containers; the redir is for protection against unintentional placement of objects |
A Few Notes on Hygiene
Don’t worry, I’m not going to talk to you about showering or deodorant. Instead, I want to talk about some things you should be doing, but probably aren’t.
Backups
Yes, backing up the DC technically also captures the GPOs. I’ve had to deal with trying to roll back GPO changes via this type of backup. I do not recommend it.
What should you do instead?
- Set up a new dedicated Tier 0 system with a data drive
- Create a GPOBackup folder with two sub-folders; Policies and Links
- Grant the system account permission to back up Group Policies
- Install the Group Policy Management Console and Active Directory Remote Server Administration Tools (RSAT)
- Create a simple PowerShell script that calls Backup-GPO and also calls Get-ADOrganizationalUnit with the gPLink property
- Run backups to the GPOBackupPolicies folder
- Export the OU name, distinguishedName, and gPLinks values to CSV under GPOBackupLinks folder with a name that includes date and time
- Create some sort of scheduled automation
- Ideally using Azure Automation or some other central orchestration tool, but can be a scheduled task
- Set the automation to run every hour
- Create a secondary automation script to run every day to remove items older than 30 days
- Back the system itself up with your regular backup tools
This gives you 30 days of hourly rollback, coupled with more time covered by your regular backup system. The best part, is that you can then recover policies very quickly, including links, without doing an authoritative restore. If you need an example script, you can find one on the Netwrix site here that looks pretty solid.
If you want a commercial solution, look into tools that implement native AD-aware backup and offer granular restore. I think Veeam offers this (see Veeam blog) as do other tools. Don’t assume that your backup product offers granular restore, even if it offers AD-aware backups.
Change Control
If you want to go a step above simple backups, implement a third-party tool to provide delegation and change control. The “big boy” option for this is something like Quest Software’s GPOAdmin. If you need something more budget friendly, SDMSoftware has a Change Manager product, which also supports Intune.
I am going to strongly suggest not trying to roll your own solution in this case. I know, shocking. You can certainly script tracking of changes, as well as triggered backups. Trying to do change management with scripts would require scripts that can create policies from a file IaC style. This approach would need to leverage source control and a CI/CD process that has approval gates. The change definition would be a file that gets pushed to a folder. The folder would be watched by a process that then creates or updates GPOs based on the file.
Automation
What? You didn’t think I would tell you that you needed to do all kinds of work and not tell you how to automate things? What kind of jerk do you think I am? (Don’t answer that…)
The downside to the Microsoft GPMC cmdlets is that they only offer you two ways to export GPO information; XML or HTML. The HTML option is really a non-starter as parsing it would just be way too much work. The XML is slightly better, but it’s still an oddly organized mess that would require weeks to work through. Normally this is where I would try to find a Windows API I could tap into. Unfortunately these are all sealed off, outside of the Microsoft.GroupPolicy namespace. The namespace doesn’t provide any options for getting the settings, so we are stuck with the module. The module does include cmdlets for retrieving the individual registry values, but nothing that will retrieve all of them en-masse. This means you either have to go through every single registry path (ew), or find another method.
Fortunately for us, there is a better way.
The same SDMSoftware that I mentioned above has a free offering that can help us out. They also have a commercial GPO Migrator tool that can help with automating this type of work. No, I’m not trying to sell you a product, just pointing out that it’s there.
So, how does this solve our problem? SDM Software also provides an absolutely free to use PowerShell module that you can get here (no mailing list). Darren and his company did all that difficult parsing work, but they dropped the limiters that the Microsoft module has. This means you can get all the values at once. Once you have the values, it’s easy to dump them out to a CSV, or even straight to Excel. Done and dusted right? Well….actually….no.
While the SDM cmdlets offer a great option for exporting the settings, the same is not true for importing. The option to do that requires purchasing their tools, which come with more comprehensive PowerShell cmdlets. This means we have to fall back to the Microsoft module to deploy our settings. This means our solution will need to involve two modules to handle both parts. We’ll also likely want to adjust the formatting so that we can possibly manipulate or generate the values. We still have a limitation, as neither tool gets stuff under Windows Settings. That means no way to grab things like the user rights assignment bits. To be fair, you shouldn’t be setting on every policy anyway, so we’ll leave that manual.
Now, because I’m such a nice guy, I’ve thrown together a quick PowerShell module. I’ll state right up front that I haven’t had time for extensive testing beyond the Pester tests that already exist. Think of this module as more of an example than a full-featured offering. That said, feel free to grab from my GitHub here. Please do test it out and let me know what you think. If there is enough interest, I may even try to flesh it out and publish it.
From a source control perspective, this export process is fantastic, because it enables you to build out your policies in a very structure manner. If you stick with this approach, you can track modifications this way as well, giving you that IaC goodness.
Conclusion
I know, this post is a lot shorter than the last one. Anyone who knows me, or those who’ve read my other posts, are likely cheering at the unusual brevity. Don’t worry though, as I’m sure I’ll more than make up for it on my next offering.
Until next time campers!
Comments