How to Backup and Recover Group Policy Objects (GPOs)

How to Backup and Recover Group Policy Objects (GPOs)

Editor’s note: This is the 5th and final blog series around Active Directory (AD) backup and recovery using STEALTHbits, StealthRECOVER. Read the 1st blog An Introduction to Active Directory Backup and Recovery, the 2nd blog Active Directory Object Recovery, the 3rd blog Active Directory Recover (Recycle Bin), and the 4th blog How to Rollback and Recover Active Directory Object Attributes.

Welcome to the final post in this Active Directory Backup and Recovery blog series, which will discuss the backup and recovery of Group Policy Objects. While Group Policy is technically distinct from Active Directory, the two solutions are very closely connected. Active Directory not only contains all of the user and computer objects that are controlled by Group Policy, but it also provides the structure that allows Group Policies to be applied to those users and computers.

Group Policy Objects Backup and Recovery

Before we dive into Group Policy Object (“GPO”) backup and recovery, let’s continue this series’ pattern of excessive context with some background information on Group Policy Objects.

The creation of a Group Policy Object within a domain is the responsibility of the Active Directory domain controller with the PDC Emulator Flexible Single Master Operator (“FSMO”) role. Windows NT domains allowed for the existence of only one writable domain controller within a domain, designated the Primary Domain Controller or “PDC”. This is the result of Windows NT’s single-master replication architecture. In contrast, Active Directory utilizes a multi-master architecture in which all domain controllers may be writable. The Active Directory PDC Emulator role was designed in part to facilitate the migration of domains from Windows NT to Active Directory.

The PDC Emulator imitates the single-master behavior of the Windows NT Primary Domain Controller, making it ideally-suited to perform certain functions such as minimizing the chances of conflicting GPO commits. It also performs a number of similarly-important functions within a domain. It serves as the authoritative source for time synchronization within a domain and is responsible for committing and replicating of especially important information, such as password changes.

When a new Group Policy Object is created the PDC Emulator assigns a GUID that is used to name each of the two pieces that comprise a Group Policy Object. This ensures that each Group Policy Object can be uniquely identified. It also helps to secure the two default Group Policies, the Default Domain Policy and the Default Domain Controllers Policy. Both are named using well-known GUIDs: The Default Domain Policy is always {31B2F340-016D-11D2-945F-00C04FB984F9} and the Default Domain Controllers Policy is always {6AC1786C-016F-11D2-945F-00C04fB984F9}.

The first piece of a Group Policy Object is the Group Policy Template (“GPT”), which is comprised of a set of folders in the SYSVOL file share (“C:\Windows\SYSVOL\domain\Policies\{GUID}\”). These folders are used to store the majority of the content of a Group Policy Object (e.g., templates, settings, scripts, details about MSI packages, etc.). The GPT is replicated to every Domain Controller by File Replication Services (“FRS”) or Distributed File System Replication (“DFSR”), depending on the version of Windows. In fact, GPOs are effectively domain-specific because SYSVOL is only replicated within a domain.

Group Policy Template

The second piece of a Group Policy Object is the Group Policy Container (“GPC”), which is a groupPolicyContainer Active Directory object located in the domain naming context under CN=System,CN=Policies. This object’s attributes are used to store referential information relating to a Group Policy Object. Significantly, this includes the gPCFileSysPath attribute, which contains the path to the Group Policy Object’s GPT in SYSVOL. Unlike the GPT, the GPC is replicated by Active Directory Domain Services according to the configured replication cost, schedule, and interval.

Group Policy Container

Once a Group Policy Object has been created, it can be associated to one or more Active Directory objects. This association is not maintained by the Group Policy Object, but by each of the Active Directory objects that have been associated to the Group Policy Object.

These associations are external to the GPO itself and are contained within the gPLink attribute which is available to three classes of Active Directory Objects, the Organizational Unit (“OU”) object, the Domain object, and the Site object. The value of an object’s gPLink attribute is a list of the GPC paths of each Group Policy Object that the object has been associated with. When a GPO’s association to an object is created or deleted, only the value of the affected object’s gPLink attribute is modified.

(NOTE: While the replication of SYSVOL effectively makes Group Policy Objects domain-specific, the fact that Group Policy Objects can be linked to a Site object means that GPO-related information is not necessarily confined to a domain. Site objects are stored in the Active Directory Configuration partition, which is replicated to all domain controllers in the forest. This results in the path to a Group Policy Object’s GPC contained in the gPLink attribute sneaking out of the domain during Active Directory replication.)

Group Policy Processing Order

The Organizational Unit, Domain, and Site objects are also a crucial piece in determining the order of precedence in a situation where there are conflicting Policies.

Group Policy Processing Order

Active Directory applies GPOs in the following order: Local Policies, Site-Linked Policies, Domain-Linked Policies, Organizational Unit-Linked Policies with the last applied Group Policy “winning” (unless the “Enforce” option is used, which prevents a Group Policy from being overridden by a subsequently applied Group Policy). Group Policies that are linked to Organizational Units are processed beginning from the root, so a GPO linked to a nested OU will take precedence over a GPO linked to its parent OU.

One last thing to note is that Group Policy Objects contain two subgroups, the Computer Configuration and the User Configuration. Both of these subgroups contain nearly identical sets of Policy settings. The principal difference between each of the subgroups is when these Policy settings are applied.

Computer Configuration settings are applied to computers during boot and User Configuration settings are applied during logon. This means that options within the Computer Configuration subgroup of a Group Policy are always enforced against associated computers, while options within the User Configuration subgroup of a Group Policy are only be enforced when an associated user account is logged on to a computer.

If a user logs on to a computer and there is a conflict between a Computer Configuration setting and a User Configuration Setting, the Computer Configuration setting will always take precedence over the User Configuration setting.

With that out of the way, let’s get back on topic and discuss GPO backup and restore.

We’ll begin with the Group Policy PowerShell cmdlets available as part of Microsoft’s Windows Remote Server Administration Tools, which conveniently happen to include both a Backup-GPO cmdlet and a Restore-GPO cmdlet. The Backup-GPO cmdlet makes it very easy to take a snapshot of all of a domain’s Group Policy Objects or a single specified Group Policy Object. The Restore-GPO cmdlet can restore a Group Policy Object to its state as captured in a backup made by the Backup-GPO cmdlet.

The following PowerShell script uses the Backup-GPO cmdlet’s -All parameter to create backups of all of the GPOs in a domain that I explicitly specify using a domain controller that I also explicitly specify. Repeatedly backing up Group Policy Objects to a single location is supported, but each execution of this script creates a unique folder for its output.

$BackupPath = '\HOSTNAME\GPOBackup\'
$Domain = 'domain.com'
$DomainController = 'DC.domain.com'

$BackupFolder = New-Item -Path $BackupPath -Name (Get-Date -format yyyyMMddTHHmmss) -ItemType Directory
Backup-GPO -All -Domain $Domain -Server $DomainController -Path $BackupFolder

The output of the Backup-GPO cmdlet consists of a separate subfolder for each GPO’s backup information and a manifest.xml file that contains the information necessary to associate each of the subfolders to their respective Group Policy Objects.

Backup-GPO cmdlet

The subfolders are named using backup-specific GUIDs that have been generated during the cmdlet execution, which all but eliminates the chance of a naming collision occurring as a result of repeated backups to a single location.

Looking inside one of the subfolders, we find that each backup consists of a folder and three XML files.

Backup-GPO cmdlet subfolder

The folder contains a copy of the Group Policy Object’s GPT and the XML files contain the data from the Group Policy’s GPC, information specific to the backup’s execution, and a report which describes the contents of the GPO.

As mentioned above, segregating the output of each execution into unique folders is not strictly necessary, though the behavior of the Restore-GPO cmdlet creates a benefit for doing so. The Restore-GPO cmdlet will allow you to restore all GPOs at once, but it will use the most recent backup of each Group Policy Object as identified within the manifest.xml. By separating each set of backups into their own folder, each set of backups gets its own manifest.xml. This allows the restoration of all of the GPOs in any of these backup sets in a single operation.

A downside to using the Backup-GPO cmdlet’s -All parameter in my script is that it backs up all of the Group Policy Objects in my domain every time it is executed.

Since we’re working with PowerShell, one way we can attempt to get around that issue is by doing something like what I’ve done in the script below.

$BackupPath = '\HOSTNAME\GPOBackup'
$Domain = 'domain.com'
$DomainController = 'DC.domain.com'

if((Test-Path "$BackupPath\lastBackup")) {
    $LastBackup = Get-Content -Path "$BackupPath\lastBackup"
    Set-Content -Path "$BackupPath\lastBackup" -Value (Get-Date)
    $GPOs = Get-GPO -All -Domain $Domain -Server $DomainController
    $GPOs | Where-Object { $_.ModificationTime -gt $LastBackup } | ForEach-Object {
        Backup-GPO -Guid $_.Id -Domain $Domain -Server $DomainController -Path $BackupPath
    }
}
else {
    Set-Content -Path "$BackupPath\lastBackup" -Value (Get-Date)
    Backup-GPO -All -Domain $Domain -Server $DomainController -Path $BackupPath
} 

This PowerShell script forces the Backup-GPO cmdlet into a differential behavior using a file the script creates in the update folder to maintain the timestamp of the script’s last runtime. If the file exists, the script backs up any of the domain’s GPOs that have been modified since the timestamp in the file. If the file doesn’t exist, the script creates the file, sets the timestamp, and backs up all of the domain’s GPOs.

While this approach will save space by limiting unnecessary backups, the backups it does make all end up in the same folder which makes it difficult to restore Group Policy Objects to a specific point in time.

Combining the approaches taken in each of the two scripts would solve all of our problems, right?

$BackupPath = '\HOSTNAME\GPOBackup'
$Domain = 'domain.com'
$DomainController = 'DC.domain.com'

$BackupFolder = New-Item -Path $BackupPath -Name (Get-Date -format yyyyMMddTHHmmss) -ItemType Directory

if((Test-Path "$BackupPath\lastBackup")) {
    $LastBackup = Get-Content -Path "$BackupPath\lastBackup"
    Set-Content -Path "$BackupPath\lastBackup" -Value (Get-Date)
    $GPOs = Get-GPO -All -Domain $Domain -Server $DomainController
    $GPOs | Where-Object { $_.ModificationTime -gt $LastBackup } | ForEach-Object {
        Backup-GPO -Guid $_.Id -Domain $Domain -Server $DomainController -Path $BackupFolder
    }
}
else {
    Set-Content -Path "$BackupPath\lastBackup" -Value (Get-Date)
    Backup-GPO -All -Domain $Domain -Server $DomainController -Path $BackupFolder
} 

As it turns out, isolating each of the differential backup results in their own folders actually makes everything far worse. This approach also isolates each of the manifest.xml files in their own folders, both effectively eliminating the ability to restore all GPOs at once while also making it incredibly difficult to find the backups associated with any specific Group Policy Object.

In practice, some limitations these approaches are running into are limitations imposed by the relatively limited capabilities of the Restore-GPO cmdlet.

# Restore a single GPO from its most recent backup
Restore-GPO -Name 'GpoName' -Path '\HOSTNAME\GPOBackup' -Domain 'domain.com' -Server 'DC.domain.com'

# Restore a single GPO from a specific backup
Restore-GPO -BackupId 12345678-09ab-cdef-1234-567890abcdef -Path '\HOSTNAME\GPOBackup' -Domain 'domain.com' -Server 'DC.domain.com' 

# Restore all of a domain’s GPOs from their most recent backup
Restore-GPO -All -Path '\HOSTNAME\GPOBackup' -Domain 'domain.com' -Server 'DC.domain.com'

The Restore-GPO can restore a specific Group Policy Object from either the most recent backup referenced in a manifest.xml file or a specified backup, but restoring all of a domain’s GPOs at once is limited to using the most recent backups in a specified manifest.xml file.

When a Group Policy Object is restored from backup, the version of the Group Policy Object is incremented as part of the restoration process.

Group Policy Object restoration

This behavior exists to force replication to favor the restored copy of the Group Policy Object.

OK, one more quick tangent.

The output from the Restore-GPO cmdlet includes two sets of version numbers, one for the Computer Configuration and one for the User Configuration.

The GPT and the GPC are each responsible for maintaining their own version number, with the separate UserVersion and ComputerVersion values being calculated from the respective User Configuration version and Computer Configuration version numbers. This is possible as a result of the way the version number is incremented. It is increased by 1 when a Group Policy Object’s Computer Configuration is modified and by 65536 each time the User Configuration is modified.

All of this is necessary because, as discussed above, a Group Policy Object’s GPT and GPC are replicated separately by different services, which can result in times when the version numbers of a Group Policy’s GPT and GPC on any specific domain controller being out of sync. do not match. While a Group Policy Object is in this state it will fail when processed. Once the version numbers are back in sync the GPO will once again process successfully.

Back to regularly scheduled programming…

A documented limitation of the Restore-GPO cmdlet is that it cannot be used to recover a Group Policy Object that has been deleted. Attempting to do so will result in an error that looks like this:

GPO Restoration error

The reason that the Restore-GPO cmdlet fails in this situation is because it is unable to find the GPC piece of the Group Policy Object in Active Directory.

If you are able to recover the GPC first, Restore-GPO actually can be used to recover a Group Policy Object. Check this out:

Restore-GPO

With the GPC back in place – in the example above, the Restore-ADObject cmdlet was used to fully-recover the Active Directory piece of the Group Policy Object from the Active Directory Recycle Bin – the Restore-GPO cmdlet is able to restore the GPO.

While this process may be capable of recovering the deleted GPO, it cannot restore the gPLink values that existed prior to the GPO’s deletion. This is because, as mentioned in arguably overwhelming detail above, those values existed on the linked objects themselves and not as part of the Group Policy Object. The only safe way around this limitation is to leverage external backups of Active Directory that contain the gPLink values.

Moving on from the Group Policy PowerShell cmdlets, Microsoft also provides the Group Policy Management Console (“GPMC”), an MMC snap-in that can be used to backup and restore Group Policy Objects. Like the Backup-GPO cmdlet, it can back up either a single specified Group Policy Object or all of a domain’s Group Policy Objects. Unlike the Restore-GPO cmdlet, it is limited to restoring a single GPO at a time.

GPMC does provide a method to restore deleted Group Policy Objects from backup, but it doesn’t actually recover the deleted GPO. It actually just creates a new GPO and populates it using the information in the backup.

Another benefit of the GPMC is an improved visibility into the contents of the GPO backups, though it remains difficult to compare the settings contained in a backup to the current settings of the live Group Policy Object.

Microsoft’s Advanced Group Policy Management (“AGPM”) tool, which is available as part of the Microsoft Desktop Optimization Pack, further extends the functionality of the GPMC with the addition of version control functionality. This helps to provide an increased capability to view and understand the contents of your backups.

However, the benefits of AGPM tend to be outweighed by both the fact that it doesn’t seem to be very well maintained and also that it has a reputation for not playing well with others (e.g., modifying an AGPM-managed GPO outside of AGPM can result in corruption of the AGPM database).

That said, it’s not necessarily a bad tool, it’s just something that I suggest you mess around with quite a bit it in a lab environment before attempting to deploy it into production.

OK, that’s a wrap on this series of blog posts.

While this series has covered quite a few methods by which different parts of Active Directory can be backed up and recovered, most of them come with caveats and none of them handle everything we’ve covered all by themselves.

That, in a nutshell, is why tools like StealthRECOVER exist. StealthRECOVER provides a single, unified web interface with fully-searchable backups and email alerts, the ability to backup both Active Directory objects and Group Policy Objects in a single snapshot, and recovery capabilities that can both restore deleted objects and rollback attribute changes to live objects. It can also recover deleted Group Policy Objects and their associated gPLinks. If you’d like to check it out, contact us today.

Don’t miss a post! Subscribe to The Insider Threat Security Blog here:

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Start a Free StealthAUDIT® Trial!

No risk. No obligation.

Privacy Preference Center

      Necessary

      Advertising

      Analytics

      Other