Group Policy backup with a PowerShell script

The PowerShell script I discuss in this post creates a Group Policy backup in a different way than with the Backup-GPO cmdlet of the Group Policy module. With my function, it will be much easier to identify the correct Group Policy Object (GPO) in case you have to restore Group Policy settings.

Let’s take a quick peek at the GPO-specific cmdlets included in the GroupPolicy module from Microsoft.

PS C:\> get-command -noun gpo

CommandType     Name                     Version    Source
-----------     ----                     -------    ------
Cmdlet          Backup-GPO               1.0.0.0    GroupPolicy
Cmdlet          Copy-GPO                 1.0.0.0    GroupPolicy
Cmdlet          Get-GPO                  1.0.0.0    GroupPolicy
Cmdlet          Get-GPOReport            1.0.0.0    GroupPolicy
Cmdlet          Import-GPO               1.0.0.0    GroupPolicy
Cmdlet          New-GPO                  1.0.0.0    GroupPolicy
Cmdlet          Remove-GPO               1.0.0.0    GroupPolicy
Cmdlet          Rename-GPO               1.0.0.0    GroupPolicy
Cmdlet          Restore-GPO              1.0.0.0    GroupPolicy

Performing a backup using Backup-GPO

Let’s a take a backup of a single GPO and see what the output looks like.

Backup-GPO -name "Default Domain Policy" - path c:\temp\gpobackup
Backup GPO output
Backup GPO output

I asked the cmdlet to back up the GPO named “Default Domain Policy.” The cmdlet created a folder that contains all the relevant parts of the GPO. However, the folder’s name is not “Default Domain Policy.” Instead it is named after the BackupID created for the GPO.

The BackupID is a 32-bit identifier that is unique for each backup. Its name matches the name of the folder containing the backup copy of the GPO. Microsoft does this so you can take multiple backups of the same GPO, save them in a common location, and separate them for later retrieval.

BackupID is unwieldy to work with in my opinion, especially if you are backing up more than one GPO. In fact, I would bet the default behavior most admins do is to backup GPOs in bulk on a regular schedule. Imagine saving a few copies of your GPOs to the same folder by BackupID and then trying to figure out which GPO is which. It is impossibly hard to manage. In this scenario, you end up with just a giant list of folders with unintelligible GUIDs.

Backup GPO output of many GPOS
Backup GPO output of many GPOS

My solution

I got frustrated with this approach and set out to make a better backup that lists my backups by GPO name instead of BackupID. However, Microsoft still requires the BackupID for restoring the GPO at a later date, so I decided to append the GPO Name to the folder created by Microsoft’s Backup-GPO cmdlet. This gives me the best of both worlds: the GPO name and the BackupID.

Since I am still using the Microsoft cmdlets to do the work, I will need to read the GPO info, backup the GPO, and finally append the GPO name with a delimiter to the newly created folder after the backup of each GPO occurs.

Finally, I want all the GPOs saved in a folder named after the backup date. For example, if I was backing up my GPOs to a network share named Group-Policy, I want a folder created called 2019-01-05 and then a subfolder for each GPO. Here’s a screenshot of how it would look:

Desired Folder Layout
Desired folder layout

For me to back up all GPOs, I would have to run the cmdlet Backup-GPO -all. The -all parameter requires a backup path and the domain name that the Group Policies are a part of. You can also specify the server, but it is not a requirement. I’ll create a function called Backup-GroupPolicy to back up all GPOs. The function will have parameters for the backup path and for the server to back up the GPOs from.

I also read the domain info and save it to a variable. I’ll name these variables $Path, $Server, and $Domain. $Server is not the greatest name. Since we really need the name of a domain controller (DC) for the cmdlet to work, $DC would be better. But Microsoft used ‑Server instead of -DC or –DomainController in their cmdlet, so I will follow suit as well in my function to be consistent and avoid confusion.

The first thing I need to do is read the current GPOs and store the info so I can manipulate it later on:

$GPOInfo = Get-GPO -All -Domain $domain -Server $Server

Then I will need to create a folder to save the GPO backups to. Remember, I have the $path variable that contains the backup path.

#Create a date-based folder to save Group Policy backups
$Date = Get-Date -UFormat "%Y-%m-%d"
$UpdatedPath = "$path\$date"
New-item $UpdatedPath -ItemType directory | Out-Null

I am using Out-Null after I create the folder to hide the output normally shown after the creation of a new folder. At this point, I have my GPO info stored in a variable and a date-based folder to save my backups to. Now I need to perform the backup and manipulate the default GPO backup settings.

The process I’ll be following is pretty simple. A loop will perform a backup of each GPO one at a time. The backup will write the data to the location specified in the $UpdatedPath variable and simultaneously save the backup metadata to some temp variables. After the backup of a GPO finishes, the process will then append the name of the GPO to the folder just created. That process will continue for each GPO in my domain.

ForEach ($GPO in $GPOInfo) {

            #Assign temp variables for various parts of GPO data
            Write-Host "Backing up GPO named: " $GPO.Displayname
            $BackupInfo = Backup-GPO -Name $GPO.DisplayName -Domain $Domain  path $UpdatedPath -Server $Server
            $GpoBackupID = $BackupInfo.ID.Guid
            $GpoGuid = $BackupInfo.GPOID.Guid
            $GpoName = $BackupInfo.DisplayName
            $CurrentFolderName = $UpdatedPath + "\" + "{"+ $GpoBackupID + "}"
            $NewFolderName = $UpdatedPath + "\" + $GPOName

            #Rename the newly created GPO backup subfolder from its GPO ID to the GPO Displayname + GUID
            rename-item $CurrentFolderName -newname $NewFolderName

The backup script

Now’s let’s put all of these bits together into a complete script:

function Backup-GroupPolicy {
<#
    .SYNOPSIS
    Backs up all existing Group Policies to a folder

    .DESCRIPTION
    Backs up all Group Policies to a folder named after the current date. Each group policy is saved in
    its own sub folder. The folder name will be the name of the Group Policy.

    Folder Name Example:
    --------------------
    C:\GPBackup\2018-12-21\Default Domain Policy


    .PARAMETER Path
    Specifies the path where the backups will be saved. 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. This is auto populated with the domain info from the PC running
    the cmdlet.

    .PARAMETER Server
    Specifies the Domain Controller to query for group Policies to backup

    .EXAMPLE
    Backup-GroupPolicy -path C:\Backup

    Description:
    This example creates a backup of the GPO's and saves them to the c:\backup folder.
    Since no server was specified, the code will search for the nearest Domain Controller.

    .EXAMPLE
    Backup-GroupPolicy -path C:\Backup -Domain nwtraders.local -Server DC01

    Description:
    This example creates a backup of GPO's in the nwtraders.local domain to the C:\Backup folder.
    The backups will be pulled from the DC named DC01.


    .NOTES
    Name       : Backup-GroupPolicy.ps1
    Author     : Mike Kanakos
    Version    : 1.1.0
    DateCreated: 2018-12-19
    DateUpdated: 2019-01-25

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

[CmdletBinding(SupportsShouldProcess=$true)]
param (
    [Parameter(Mandatory=$True,Position=0)]
    [string]
    $Path,

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

    [Parameter()]
    [string]
    $Server
    )

    begin {

        # Get current GPO information
        $GPOInfo = Get-GPO -All -Domain $domain -Server $Server


        #Create a date-based folder to save backup of group policies
        $Date = Get-Date -UFormat "%Y-%m-%d"
        $UpdatedPath = "$path\$date"

        New-item $UpdatedPath -ItemType directory | Out-Null

        Write-Host "GPO's will be backed up to $UpdatedPath" -backgroundcolor white -foregroundColor red
    } #end of begin block

    process {

        ForEach ($GPO in $GPOInfo) {

            Write-Host "Backing up GPO named: " -foregroundColor Green -nonewline
            Write-Host $GPO.Displayname -foregroundColor White

            #Assign temp variables for various parts of GPO data
            $BackupInfo = Backup-GPO -Name $GPO.DisplayName -Domain $Domain -path $UpdatedPath -Server $Server
            $GpoBackupID = $BackupInfo.ID.Guid
            $GpoGuid = $BackupInfo.GPOID.Guid
            $GpoName = $BackupInfo.DisplayName
            $CurrentFolderName = $UpdatedPath + "\" + "{"+ $GpoBackupID + "}"
            $NewFolderName = $UpdatedPath + "\" + $GPOName + "___" + "{"+ $GpoBackupID + "}"
            $ConsoleOutput = $GPOName + "___" + "{"+ $GpoBackupID + "}"

            #Rename the newly created GPO backup subfolder from its GPO ID to the GPO Displayname + GUID
            rename-item $CurrentFolderName -newname $NewFolderName


        } #End ForEach loop

    } #End of process block

    end {
    } #End of End block
} #End of function

You can run this function as needed or schedule it to run regularly via a scheduled task or a scheduled job. Once scheduled, it’s one less thing you have to perform manually each month. If you work at a company that uses GPOs heavily, this function may take a good bit of time to run. I have approximately 150 GPOs in my employer’s domain, and the script takes just a few short minutes to complete. The script will show the name of each GPO it’s backing up when running it, so you can get an idea of how much work it has completed.

Script output in progress
Script output in progress

Conclusion

I built this function because I was not happy with the default output from the built-in Microsoft tools. That’s what makes PowerShell so great: if something doesn’t work as expected, you can build your own tool! My hope is that this tool will become a useful addition in your sysadmin arsenal. Be on the lookout for a follow-up article that walks you through the restore process using a script I wrote that was designed to do restores specifically from the backups created by this tool.

Last but not least, all my scripts are constantly under revision as I find new ways to improve them. You can find the latest version of all my scripts at my Github PowerShell repo. Let me know what you think in the comment section below. Thanks for reading!

Subscribe
Notify of
guest

41 Comments
Michael Webber
Michael Webber
Guest
7 years ago

I see on line 91, the hyphen is missing from path.  It should be -path.

Michael Pietroforte
Reply to  Michael Webber
7 years ago

That was my bad. Must have happened when I edited the text. However, I have no idea how because I just copy and pasted the code.

Fabian Niesen
Guest
7 years ago

I had the same thoughts in 2014, that’s the reason why I wrote my GPOBackups script and shared it at the Technet Gallary since this time. Meanwhile, including retention period, Eventlog entries, filtering for nonusable characters and HTML-Reports.

If you like to take look for some extensions: bit.ly/gpobackup

Luc Fullenwarth
7 years ago

I never thought that having to deal with GUIDs could be an issue.
That’s probably because I never had to restore GPOs until now… 😉

Thanks for the post!

Jamie Cottrell
Jamie Cottrell
Guest
7 years ago

For me I could not get restores to work using this script. I updated the foreach loop to the following:

ForEach ($GPO in $GPOInfo) {

$BackupFolder = New-Item $UpdatedPath\$($GPO.Displayname) -ItemType directory
#Assign temp variables for various parts of GPO data
Write-Host “Backing up GPO named: ” $GPO.Displayname
Backup-GPO -Name $GPO.DisplayName -Domain $Domain -path $BackupFolder.FullName -Server $Server

} #End ForEach loop

Now this is wokring for getting the restore GPO to work correctly.

Jamie Cottrell
Jamie Cottrell
Guest
Reply to  Mike Kanakos
7 years ago

Sure. So there where no errors with running the code as supplied. But I then went to test a restore of one of the GPO’s. When I ran the Restore-GPO cmdlet I got the following error:

Restore-GPO -Name ‘TEST’ -Path ‘C:\temp\2019-01-21\TEST\’

Restore-GPO : There were no GPO backups found at path “C:\temp\2019-01-21\TEST\”.
Parameter name: Path
At line:1 char:1
+ Restore-GPO -Name ‘TEST’ -Path ‘C:\temp\2019-01-21\TEST\’
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Restore-GPO], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.GroupPolicy.Commands.RestoreGpoCommand

I also tried to to restore the GPO via the Group Policy Management MMC snapin and this came up with ‘No Backups found’ when pointing the backup location to the specified folder.

I think this has to do with the manifest.xml file. If you do a single backup you will see that the folder with the GUID is created as well as a manifest.xml file. In your code above you are only renaming the GUID folder name, but not doing anything with the manifest.xml file. So as the script loops through each GPO the manifest.xml file gets overwritten each time.

Based on the above it seems like the maifest.xml file is needed to process the restore. Thats why I’ve changed the loop. My version now creates the folder with the GPO name then just backs up the GPO into that folder. That keeps the organisation of having the GPO folder names and also keeps the manifest.xml and GUID folder in tact.

After making the change to the loop I can now run the Restore-GPO cmdlet that was getting the error and sucessfully restore the GPO.

Mallikarjun
Guest
7 years ago

I’m trying to execute the script but I’m getting the error..I have pasted the error  at the end of the script..

Can you address this issue Please..Many thanks.

My domain name :- ABC.com
My server name :- DC1.ABC.com
Path to save :- C:\Backups.

Script :-

[CmdletBinding(SupportsShouldProcess=$true)]
param (
[Parameter(Mandatory=$True,Position=0)]
[string]
$Path,

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

[Parameter()]
[string]
$Server
)

begin {

#Get current GPO information
import-module GroupPolicy
$GPOInfo = Get-GPO -All -Domain ABC.COM -Server DC1.ABC.COM

#Create a date-based folder to save a backup of Group Policies to
$Date = Get-Date -UFormat “2019-01-21”
$UpdatedPath = “c:\backups\$date”

New-item $UpdatedPath -ItemType directory | Out-Null

Write-Host “Will back up GPOs to $UpdatedPath”
} #End of begin block

process {

ForEach ($GPO in $GPOInfo) {

#Assign temp variables for various parts of GPO data
Write-Host “Backing up GPO named: ” $GPO.Displayname
$BackupInfo = Backup-GPO -Name $GPO.DisplayName -Domain $Domain -path $UpdatedPath -Server $Server
$GpoBackupID = $BackupInfo.ID.Guid
$GpoGuid = $BackupInfo.GPOID.Guid
$GpoName = $BackupInfo.DisplayName
$CurrentFolderName = $UpdatedPath + “\” + “{“+ $GpoBackupID + “}”
$NewFolderName = $UpdatedPath + “\” + $GPOName

#Rename the newly created GPO backup subfolder from its GPO ID to the GPO Displayname
rename-item $CurrentFolderName -newname $NewFolderName

} #End ForEach loop

} #End of process block

Error message :-

Will back up GPOs to c:\backups\2019-01-21
Backing up GPO named:  GPO3
Backup-GPO : Cannot validate argument on parameter ‘Server’. The argument is null or empty. Supply an argument that
is not null or empty and then try the command again.
At line:37 char:103
+             $BackupInfo = Backup-GPO -Name $GPO.DisplayName -Domain $Domain -path $UpdatedPath -Server <<<<  $Serv
er
+ CategoryInfo          : InvalidData: (:) [Backup-GPO], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.GroupPolicy.Commands.BackupGpoCommand

Rename-Item : Cannot rename because item at ‘c:\backups\2019-01-21\{}’ does not exist.
At line:45 char:24
+             rename-item <<<<  $CurrentFolderName -newname $NewFolderName
+ CategoryInfo          : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand

Backing up GPO named:  GPO2
Backup-GPO : Cannot validate argument on parameter ‘Server’. The argument is null or empty. Supply an argument that
is not null or empty and then try the command again.
At line:37 char:103
+             $BackupInfo = Backup-GPO -Name $GPO.DisplayName -Domain $Domain -path $UpdatedPath -Server <<<<  $Serv
er
+ CategoryInfo          : InvalidData: (:) [Backup-GPO], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.GroupPolicy.Commands.BackupGpoCommand

Rename-Item : Cannot rename because item at ‘c:\backups\2019-01-21\{}’ does not exist.
At line:45 char:24
+             rename-item <<<<  $CurrentFolderName -newname $NewFolderName
+ CategoryInfo          : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand

Backing up GPO named:  Default Domain Policy
Backup-GPO : Cannot validate argument on parameter ‘Server’. The argument is null or empty. Supply an argument that
is not null or empty and then try the command again.
At line:37 char:103
+             $BackupInfo = Backup-GPO -Name $GPO.DisplayName -Domain $Domain -path $UpdatedPath -Server <<<<  $Serv
er
+ CategoryInfo          : InvalidData: (:) [Backup-GPO], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.GroupPolicy.Commands.BackupGpoCommand

Rename-Item : Cannot rename because item at ‘c:\backups\2019-01-21\{}’ does not exist.
At line:45 char:24
+             rename-item <<<<  $CurrentFolderName -newname $NewFolderName
+ CategoryInfo          : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand

Backing up GPO named:  GPO1
Backup-GPO : Cannot validate argument on parameter ‘Server’. The argument is null or empty. Supply an argument that
is not null or empty and then try the command again.
At line:37 char:103
+             $BackupInfo = Backup-GPO -Name $GPO.DisplayName -Domain $Domain -path $UpdatedPath -Server <<<<  $Serv
er
+ CategoryInfo          : InvalidData: (:) [Backup-GPO], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.GroupPolicy.Commands.BackupGpoCommand

Rename-Item : Cannot rename because item at ‘c:\backups\2019-01-21\{}’ does not exist.
At line:45 char:24
+             rename-item <<<<  $CurrentFolderName -newname $NewFolderName
+ CategoryInfo          : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand

Backing up GPO named:  Default Domain Controllers Policy
Backup-GPO : Cannot validate argument on parameter ‘Server’. The argument is null or empty. Supply an argument that
is not null or empty and then try the command again.
At line:37 char:103
+             $BackupInfo = Backup-GPO -Name $GPO.DisplayName -Domain $Domain -path $UpdatedPath -Server <<<<  $Serv
er
+ CategoryInfo          : InvalidData: (:) [Backup-GPO], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.GroupPolicy.Commands.BackupGpoCommand

Rename-Item : Cannot rename because item at ‘c:\backups\2019-01-21\{}’ does not exist.
At line:45 char:24
+             rename-item <<<<  $CurrentFolderName -newname $NewFolderName
+ CategoryInfo          : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand
_________________________________________________________________________________________________________________

_________________________________________________________________________________________________________________

 

Mallikarjun
Guest
7 years ago

Hi Mike,

I’m looking for taking the GPO has backup with Group policy object name..

You wrote the 1st script and that’s for taking the GPO for the backup..

I have used the same script and getting the error as mentioned above.. Can you address this issue.

Regards,
Mallikarjun.

Mallikarjun
Guest
7 years ago

Hi Mike Kanakos ,

thanks for your response.. Please see the script mentioned below and let me know what modification required to execute this script without error.. This script will take backup of all the group policy object.

CmdletBinding(SupportsShouldProcess=$true)]

param (

[Parameter(Mandatory=$True,Position=0)]

[string]

$Path,

[Parameter()]

[string]

$Domain = (Get-WmiObject Win32_ComputerSystem).Domain,

[Parameter()]

[string]

$Server

)

begin {

#Get current GPO information

$GPOInfo = Get-GPO -All -Domain tenet.adlab.test -Server USW04DC420.tenet.adlab.test

#Create a date-based folder to save a backup of Group Policies to

$Date = Get-Date -UFormat “2019-01-22”

$UpdatedPath = “E:\GPbackups\$date”

New-item $UpdatedPath -ItemType directory | Out-Null

Write-Host “Will back up GPOs to $UpdatedPath”

} #End of begin block

process {

ForEach ($GPO in $GPOInfo) {

#Assign temp variables for various parts of GPO data

Write-Host “Backing up GPO named: ” $GPO.Displayname

$BackupInfo = Backup-GPO -Name $GPO.DisplayName -Domain $Domain -path $UpdatedPath -Server $Server

$GpoBackupID = $BackupInfo.ID.Guid

$GpoGuid = $BackupInfo.GPOID.Guid

$GpoName = $BackupInfo.DisplayName

$CurrentFolderName = $UpdatedPath + “\” + “{“+ $GpoBackupID + “}”

$NewFolderName = $UpdatedPath + “\” + $GPOName

#Rename the newly created GPO backup subfolder from its GPO ID to the GPO Displayname

rename-item $CurrentFolderName -newname $NewFolderName

} #End ForEach loop

} #End of process block

Regards,
Mallikarjun.

 

Karel
Karel
Guest
7 years ago

Hi Mike,

Your script looks super promising.

I’m just not clear on where I should define the parameters.

Maybe you could make it a little more dummy proof and point out exactly where in the script the parameters should be defined. It would really help me if you told me on which line # I should put the domain, server, and destination path.
Sorry for asking stupid questions.

Great work btw!

KR,

Kim

William Batzle
William Batzle
Member
7 years ago

Hi Mike,

Any chance you have a process on using this function in a scheduled task?

William Batzle
William Batzle
Member
Reply to  William Batzle
7 years ago

Hi Mike,

Sorry for the late reply back on this and hopefully you didn't get annoyed at my stupidly put together question. So what I meant to ask was are you going to put together an article on getting this function to work in a scheduled task? I figured it all out on my own on Server 2008 and 2016. The method that works in 2008 works on 2008 and 2016. However the method I got to work does not work on 2008. Would it be ok to post my directions on how to do it and reference this article?

Sincerely,

Will

Tom
Tom
Guest
7 years ago

Hi!

I had to modify your script to get working on my domain,

GPO names can have invalid characters that the filesystem can't use, so I had to insert the line

$SafeGpoName = $GpoName.Split([IO.Path]::GetInvalidFileNameChars()) -join '_'

To allow for the names to be saved, albeit modified.

Thanks

 

 

Basavaraj R Navalgund
Basavaraj R Navalgund
Guest
6 years ago

Hi Mike,

Thank you for this script.

It  is one which saves lots of time in manipulating the name of the GPO versus GPO ID.

Regards

Raj

 

Brent
Brent
Guest
6 years ago

Any suggestions on using your restore script to restore the backups to another domain?

jerry
jerry
Guest
6 years ago

Dear Mike

Im trying to create a script to reset windows 10 workstations to the default GPO. Would you have any examples ? I would be pushing it out thru Intune.

Any advise would be appreciated.

Jerry Gomez
Jerry Gomez
Guest
6 years ago

Hello Mike

I wanted to know if you had seen any scripting for resetting's Group Policy for windows 10 OS. We are looking to reset to factory status. We would push out thru Azure / Intune.  If you have any ideas, please let me know. Thanks in advance.

J

jerry gomez
jerry gomez
Member
6 years ago

Hello Mike

Thanks for the response. We initially pushed out thru Intune some GPO's. Now we just want to reset to Windows 10 factory settings. I put together some code below? Do you think I can execute to reset all back to default, without a reboot? Afterwards we will request employee to reboot.

What do you think?

Jerry

   #  Clear GPO Config   #
   #     by Jerry             #
  #    Last Updated     #
 #     09-18-2019      #
#######################

if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
    if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
        $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArgument
        Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
    Exit
    }
}

RD /S /Q "%WinDir%\System32\GroupPolicyUsers"
RD /S /Q "%WinDir%\System32\GroupPolicy"

Joseph
Joseph
Guest
6 years ago

Hi this may seem silly, but I cannot see where to exactly add my path data or server if that is needed.

 

I saved the newest script from github, made a new drive E:\ with 40 GB of data.

The server this is running on is a DC so I want to backup the GPOs from it to this directory "E:\GPObackups\backups"

I'm not sure if the server can be blank or can be localhost but assuming the name is DC02 and that path above what changes or where exactly do I put these settings in the Backup-GroupPolicy.ps1 in order to get this to work and backup to that folder?

Once it works once I will schedule a task for each night.

 

 

 

Getting errors like this currently:

 

PS E:\GPObackups> E:\GPObackups\Backup-GroupPolicy.ps1
At E:\GPObackups\Backup-GroupPolicy.ps1:11 char:25
+     ——————–
+                         ~
Missing expression after unary operator '–'.
At E:\GPObackups\Backup-GroupPolicy.ps1:12 char:5
+     CGPBackup2018-12-21Default Domain Policy
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~
Unexpected token 'CGPBackup2018-12-21Default' in expression or statement.
At E:\GPObackups\Backup-GroupPolicy.ps1:58 char:1
+ [CmdletBinding(SupportsShouldProcess=$true)]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unexpected attribute 'CmdletBinding'.
At E:\GPObackups\Backup-GroupPolicy.ps1:59 char:1
+ param (
+ ~~~~~
Unexpected token 'param' in expression or statement.
At E:\GPObackups\Backup-GroupPolicy.ps1:61 char:13
+     [string]
+             ~
Missing closing ')' in expression.
At E:\GPObackups\Backup-GroupPolicy.ps1:64 char:16
+     [Parameter()]
+                ~
An expression was expected after '('.
At E:\GPObackups\Backup-GroupPolicy.ps1:1 char:29
+ function Backup-GroupPolicy {
+                             ~
Missing closing '}' in statement block or type definition.
At E:\GPObackups\Backup-GroupPolicy.ps1:71 char:5
+     )
+     ~
Unexpected token ')' in expression or statement.
At E:\GPObackups\Backup-GroupPolicy.ps1:81 char:29
+         $UpdatedPath = $path$date
+                             ~~~~~
Unexpected token '$date' in expression or statement.
At E:\GPObackups\Backup-GroupPolicy.ps1:110 char:5
+     } #end of process block
+     ~
Unexpected token '}' in expression or statement.
Not all parse errors were reported.  Correct the reported errors and try again.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingExpressionAfterOperator
 

Grim
Grim
Guest
6 years ago

Hi Mike,

Great script but unforuntately I've run into an issue. The company I work for has a specific name format for their GP's that I can't change. An example of a policy name here would be:

| Test | Policy Name

Running the script gives the following error due to | being an illegal character.

rename-item : Illegal characters in path.
At C:\Backups\Backup-GroupPolicy.ps1:105 char:13
+             rename-item $CurrentFolderName -newname $NewFolderName
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Rename-Item], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.RenameItemCommand

The exported backups are then in folders just using the GUID.

Eric
Eric
Guest
6 years ago

Hi,

Thanks for your script.

I noticed a problem with the github version :

This line doesn't test the path correctly :
If (-Not $UpdatedPath) { New-item $UpdatedPath -ItemType directory | Out-Null }

Should be something like :
If (!(Test-Path $UpdatedPath)) { New-item $UpdatedPath -ItemType directory | Out-Null }

Or maybe it works with Powershell without Test-Path with version > 6 ?

For those wondering how to use the function :

You can remove the first line and last line to turn it into a script.
Or
You can source it and then use it : > . .\script.ps1
Or
You can import it : > Import-module .\script.ps1 -Force

Cheers

Sus
Sus
Guest
6 years ago

It helped me a lot!

SysAD
SysAD
Guest
3 years ago

I am trying to use this script, but it’s just doing “nothing” when I run it.

PS C:\Scripts> .\Backup-GroupPolicy -Path “C:\Scripts\GPO_BUs” -Server DC
PS C:\Scripts>

Any insight on this?

Alexander Bacher
Alexander Bacher
Guest
2 years ago

Hi Mike,

this looks awesome and would be really helpful to use your script. Thank you very much in adcance.
I’m just not gettin’ how I can get this up and running.

Just downloaded your Script and fired it up within a powershell session on one of our DC’s. It’s gettin’ executed with no more output, so I assume the function is now loaded correctly.

PS C:\Temp> .\Backup-GroupPolicy.ps1
PS C:\Temp>

BUT it isn’t. It’s just not there. I can’t call the function from the same powershell-session.

PS C:\> Backup-GroupPolicy -path D:\GPO_Backup
Backup-GroupPolicy : The term ‘Backup-GroupPolicy’ is not recognized as the name of a cmdlet, function, script file,
or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
try again.
At line:1 char:1
+ Backup-GroupPolicy -path D:\GPO_Backup
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Backup-GroupPolicy:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

What I’m missing?

Thanks for your help

David Figueroa
Member
2 years ago

Like MIke K. said right before your post – you need to load the function into memory.
If it is in c:\temp, then you would type in a period, a space, and the path to the script.

. c:\temp\Backup-GroupPolicy.ps1

David F.

Alexander Bacher
Alexander Bacher
Guest
Reply to  David Figueroa
2 years ago

Oh my God … that did the trick.

For me it was the same if I’m navigate to the path and call the script with a period in front but its not!
It worked like a charm after adding the complete path to the string.

Thank you very much

David Figueroa
Member
2 years ago

You’re welcome. It’s all a matter of the script – if it defines a function, you have to dot source it. But you can also write scripts that don’t have the “define function {}” text and then you can run it directly like you were trying to. 🙂

David F.

WindowsUpdatePreventer
Scroll to Top