- Export and import to and from Excel with the PowerShell module ImportExcel - Thu, Apr 21 2022
- Getting started with the PSReadLine module for PowerShell - Thu, Feb 24 2022
- SecretsManagement module for PowerShell: Save passwords in PowerShell - Tue, Dec 22 2020
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:
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.
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.
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
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
Hello,
I know this an old posting but, I’ve just testing this and on the restore function I’m getting an error – (I’m moving Group Policies between domains to test), the error is:
Restore-GPO : Value does not fall within the expected range.
At C:\GroupPolicyBackUp\Restore-GroupPolicy.ps1:116 char:9
+ Restore-GPO -BackupID $GUID -Path $path -Domain $Domain -Serv …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Restore-GPO], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.GroupPolicy.Commands.RestoreGpoCommand
Is this because it was backed up on another Domain?
Many thanks