Today, I am sharing a PowerShell script that allows you to restore Group Policy from backups. My restore function is a companion tool to the Group Policy backup tool I shared with 4sysops readers earlier this year.

As a quick refresher, the backup tool I built saves Group Policy backups with easy-to-read folder names rather than GUIDs as filenames, which is what you would get from the default Backup-GPO cmdlet from Microsoft. When you have a large number of Group Policy Objects (GPOs) backed up with GUIDs, it's not easy to figure out which backup file is the one you need when it comes time to restore data. My backup tool solves that problem.

Once you start using my backup tool to back up Group Policy, the built-in Restore-GPO cmdlet will not read the backups my tool creates. Why? The built-in cmdlet is looking for files named as GUIDs, and my backup tool renames the files to a different naming convention.

But fear not! My backup tool makes backing up GPOs super easy, and restoring GPOs with this companion tool is also a very easy process. Let me walk you through the operation of the Restore-GroupPolicy function. If you are not familiar with my backup tool, I recommend you visit my write-up first so you can easily follow along here.

Backing up to restore ^

To show off the restore process, I'll start by creating a new Group Policy. From there I'll back it up, delete it, and finally restore the policy back to a domain controller (DC) to demonstrate the end-to-end process and how easy it is to do. So let's get started by creating a GPO we can test with. We can do this from PowerShell like so:

New-GPO -name "Dummy GPO for Testing"

After creating the GPO, we should get a summary of the new GPO info, like so:

DisplayName      : Dummy GPO for Testing
DomainName       : MK.LAB
Owner            : MK\Domain Admins
Id               : d0b1e1c0-3108-464f-8ba2-98b6b5a3b027
GpoStatus        : AllSettingsEnabled
Description      :
CreationTime     : 6/16/2019 5:12:59 PM
ModificationTime : 6/16/2019 5:13:04 PM
UserVersion      : AD Version: 0, SysVol Version: 0
ComputerVersion  : AD Version: 0, SysVol Version: 0
WmiFilter        :

Here’s a quick screenshot to show that the GPO now exists in my domain:

Creating a test GPO

Creating a test GPO

The next step would be to back up this GPO using the Backup-GroupPolicy cmdlet I talked about earlier in this article. The syntax for this cmdlet is very simple. You need to specify a path for the backup, the domain name, and the server to back up the data from. This will back up all GPOs to the path specified. The cmdlet will create a subfolder with today's date and store the backups in that subfolder.

Backup-GroupPolicy -path C:\Backup\Group-Policy -Domain MK.local -Server DC01

When the backup completes, we have a folder that contains all the GPO backups. Notice the backup of the Group Policy named "Dummy GPO for Testing" has a modified folder name that consists of the friendly name of the GPO and the actual backup ID of the GPO.

GPO backup confirmation

GPO backup confirmation

Once we have a valid backup, we can go ahead and delete the Dummy GPO. Again, we can do this via PowerShell.

Remove-GPO -name "Dummy GPO for Testing"

Restore-GroupPolicy syntax ^

Restoring a GPO from backup with the Restore-Group-Policy cmdlet is a simple process similar to the backup process we followed earlier. To perform a restore, we provide similar information like we did during backup. We need to provide three pieces of information: the exact name of the Group Policy backup, the location of the backup, and the DC to perform the restore to. For our demonstration, the syntax is:

Restore-GroupPolicy -name "Dummy GPO for Testing___{0aa714c2-a70f-4383-9011-29a5b7a9a389}"-Path "c:\backups\Group-Policy\2019-06-16" -Server DC01

When we execute the command, the cmdlet reaches out to the folder, reads the GPO backup, and initiates the restore process. Once the process completes, it returns the summary information.

DisplayName      : Dummy GPO for Testing
DomainName       : MK.LOCAL
Owner            : MK\Domain Admins
Id               : d0b1e1c0-3108-464f-8ba2-98b6b5a3b027
GpoStatus        : AllSettingsEnabled
Description      :
CreationTime     : 6/16/2019 8:53:18 PM
ModificationTime : 6/16/2019 8:53:21 PM
UserVersion      : AD Version: 0, SysVol Version: 0
ComputerVersion  : AD Version: 0, SysVol Version: 0
WmiFilter        :

Notice the time of GPO creation has changed to the time I ran the restore (approximately two and half hours after I ran the first backup). We now have our Dummy GPO restored to the SYSVOL folder on a DC without any issue, and it only took one command to get back a working copy of the GPO. Active Directory will then replicate that GPO to all the other DCs in my domain.

Restore-GroupPolicy code ^

The Restore-GroupPolicy cmdlet doesn't have a bunch of complex code. Most of the code is creating some temp variables and then temporarily renaming the file path to those variables. After creating the temp variables, it passes all the info to the built-in Group Policy cmdlets from Microsoft to do the actual GPO restore.

# Variable to hold the concatenated full original path
    $FullOriginalPath = $path + "\" + $Name

    #Create temp variables to hold just the GUID two different ways
    $TempFolderName = $Name -replace '^.+_{3}'
    $GUID = $TempFolderName -replace '^\{|\}$'

    # Create a temp variable to hold the temporary updated full path
    $FullTempPath = $path + "\" + $TempFolderName

    $Connection = Test-path $FullOriginalPath

    If(!($Connection)) {
        Write-Warning "Folder " $FullOriginalPath "is not reachable!"
        } #end if

    Else {

        #Rename the specified GPO folder to just the GUID
        Rename-item  $FullOriginalPath -newname $FullTempPath

        Restore-GPO -BackupID $GUID -Path $path -Domain $Domain -Server $Server

        #Rename the folder from a GUID back to the original folder name
        Rename-item  $FullTempPath -newname $FullOriginalPath

    } #End else

That's the main portion of the code for this script. When I write scripts, I always prefer to write functions because they include help and examples, and also the code becomes portable. The Restore-GroupPolicy cmdlet is a function, so make sure you load it into memory before you attempt to run it. You can find the full script below. The latest versions of all of my scripts are always located in my GitHub repo. I hope you find this tool and all of my others worthy additions to your sysadmin tool kit. Please reach out via the comments section if you have any questions about this or any of my other scripts.

Subscribe to 4sysops newsletter!

function Restore-GroupPolicy {
<#
    .SYNOPSIS
        Restores a Group Policy from a previous GPO backup.

    .DESCRIPTION
        Restores a Group Policy from a previous GPO backup.

        This function is intended for use with backups created by the Backup-GroupPolicy cmdlet written by Mike
        Kanakos. The built-in Restore-GPO cmdlet should be used for restoring backups made from the built-in cmdlet
        named Backup-GPO from Microsoft.

    .PARAMETER Name
        Specifies the folder of the GPO you would like to restore. The folders created by the Backup-GroupPolicy cmdlet will
        be a combination of the Name of the GPO and the BackupID GUID of the GPO.

        An example of a valid folder name would be:
        Default Domain Controllers Policy___{697ebe7d-019d-46e6-91c2-c5c85ce3f160}

    .PARAMETER Path
        Specifies the path where the backups currently exist. The path can be a local folder or a network-based folder.
        This is a required parameter. Do not end the path with a trailing slash. A slash at the end will cause an error!

        Correct format:
        c:\backups or \\server\share

        Incorrect Format:
        c:\Backups\ or \\server\share\

    .PARAMETER Domain
        Specifies the domain to look for Group Policies in. This is auto populated with the domain info from the PC
        running the cmdlet.

    .PARAMETER Server
        Specifies the name of the domain controller contacted to complete the operation.
        You can specify either the fully qualified domain name (FQDN) or the host name. If you do not specify the name
        by using the Server parameter, the primary domain controller (PDC) emulator is contacted.

    .EXAMPLE
        Restore-GroupPolicy -name "Default Domain Policy___{f4c29b97-03d3-45da-894a-e1cf7f68f276}"
        -Path "\\server01\backups\Group-Policy\2019-01-25" -Server DC01

        Description:
        Restores the GPO named Default Domain Policy from the folder named
        Default Domain Policy___{f4c29b97-03d3-45da-894a-e1cf7f68f276}. Restores the GPO to the domain controller named DC01.

        The domain name is auto-added to the back-end code without requiring input from console.

    .NOTES
        Name       : Restore-GroupPolicy.ps1
        Author     : Mike Kanakos
        Version    : 1.0.2
        DateCreated: 2019-01-25
        DateUpdated: 2019-01-26

    .LINK
        https://github.com/compwiz32/PowerShell
#>

[CmdletBinding(SupportsShouldProcess=$true)]
param (
    [Parameter(Mandatory=$True,Position=0,
    HelpMessage="Enter the folder name of the GPO that needs to be restored")]
    [alias("GroupPolicy","GPO","FolderName")]
    [string]
    $Name,

    [Parameter()]
    [string]
    $Path,

    [Parameter()]
    [string]
    $Domain = (Get-WmiObject Win32_ComputerSystem).Domain,

    [Parameter()]
    [string]
    $Server
    )

    #Variable to hold the concatenated full original path
    $FullOriginalPath = $path + "\" + $Name

    #Create temp variables to hold just the GUID two different ways
    $TempFolderName = $Name -replace '^.+_{3}'
    $GUID = $TempFolderName -replace '^\{|\}$'

    #Create a temp variable to hold the temporary updated full path
    $FullTempPath = $path + "\" + $TempFolderName


    $Connection = Test-path $FullOriginalPath

    If(!($Connection)) {
        Write-Warning "Folder " $FullOriginalPath "is not reachable!"
        } #end if

    Else {

        #Rename the specified GPO folder to just the GUID
        Rename-item  $FullOriginalPath -newname $FullTempPath

        Restore-GPO -BackupID $GUID -Path $path -Domain $Domain -Server $Server

        #Rename the folder from a GUID back to the original folder name
        Rename-item  $FullTempPath -newname $FullOriginalPath

    } #End else


} #End of function
avataravatar
1 Comment
  1. Jonathan Preetham 12 months ago

    Hi Mike,

    Below is the one line command which is used to restore the dummy GPO

    Restore-GPO -Name "Dummy GPO for Testing___{20ee8a68-c403-446a-a5c0-23e398e07325}"-Path "C:\Temp\2020-12-13" -Server ChildDC-1 -Domain "chennai.india.LOCAL"

    I have additionally added -Domain

    Below is the error which I'm receiving when I'm trying to restore..

    PS C:\windows\system32> Restore-GPO -Name "Dummy GPO for Testing___{20ee8a68-c403-446a-a5c0-23e398e07325}"-Path "C:\Temp\2020-12-13" -Server ChildDC-1 -Domain "chennai.india.LOCAL"
    Restore-GPO : There were no GPO backups found at path “C:\Temp\2020-12-13”.
    Parameter name: Path
    At line:1 char:1
    + Restore-GPO -Name "Dummy GPO for Testing___{20ee8a68-c403-446a-a5c0-23e398e07325 ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [Restore-GPO], ArgumentException
        + FullyQualifiedErrorId : System.ArgumentException,Microsoft.GroupPolicy.Commands.RestoreGpoCommand

Leave a reply

Please enclose code in pre tags

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

*

© 4sysops 2006 - 2021

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account