none
Backup-GPO -All, can this be filtered? RRS feed

  • Question

  • Hi guys,

    I'm using the following to backup all the GPO's in the domain:

    $Backups = Backup-GPO -All -Path $SubBackupFolder -Domain $DomainFQDN -Comment "Add comment here"

    However, I do not want to backup all the GPO's. I want to backup only about 20 Gpo's found inside 2 OU's. Is this achievable via backup-gpo? Rather than the -All parameter can I instead say -All that are inside these 2 OU's. All the GPO's I want to backup contain the words "win7" somewhere within the GPO name if that helps.

    I'm using Ian's script "Comprehensive Group Policy Backup Script" that performs a backup and there's a script that imports the exported data as well. Keeps links, gpo settings, delegation, etc etc..

    Thank you so much for your help.


    • Edited by Mustafa-s Friday, February 14, 2014 6:28 PM
    Friday, February 14, 2014 6:26 PM

Answers

  • The -Name parameter is still only setup to take a single computer name, not multiple names. However, there is a way to accomplish what you're after by looping through your result set.

    $GPOs = Get-GPO -All | where {$_.DisplayName -like '*win7*'}
    
    
    foreach ($GPO in $GPOs) {
        Backup-GPO -Name $GPO.DisplayName -Path 'C:\GPO-Backup'
    }



    Friday, February 14, 2014 7:27 PM
  • Hi Mustafa-s,

    Please try the script below and feedback, which make a little modification:

    $Backups=get-gpo -all | where{$_.DisplayName -like '*win7*'}| foreach {
    backup-gpo $_.displayname -Path $SubBackupFolder -Domain $DomainFQDN -Comment "Scripted backup created by $env:userdomain\$env:username on $(Get-Date -format d)"
    }

    Best Regards,

    Anna

    Tuesday, February 18, 2014 6:21 AM
    Moderator

All replies

  • Hi,

    I haven't done this myself (and I don't have a test machine at the moment), but this is what I'd try:

    Use Get-GPO to get all GPOs, then filter those with Where, then pipe those to Backup-GPO.


    Don't retire TechNet! - (Don't give up yet - 12,575+ strong and growing)

    Friday, February 14, 2014 6:38 PM
    Moderator
  • GPOs are not located in OUs, they are linked to OUs. In taking a look at the Backup-GPO cmdlet you can either backup a single GPO or all the GPOs (PowerShell 3.0 on Windows 7). Sadly the none of the parameters, such as -Name, are designed to take a string of GPO names that would allow you to back up more than one but not them all.
    Friday, February 14, 2014 6:43 PM
  • Hi Mike,

    Thanks for the response. I think I understand what you're saying, I now need to find out how to do it. I'm a complete scripting beginner. I can read scripts but cant write, I'll read up on filtering with Where and piping. BTW here is the complete script I'm working with:

    ##########################################################################################################
    <#
    .SYNOPSIS
        Backs up all GPOs from a specified domain and includes additional GPO information.
    
    .DESCRIPTION
        The script backs up all GPOs in a target domain and captures additional GPO management information, such
        as Scope of Management, Block Inheritance, Link Enabled, Link Order, Link Enforced and WMI Filters.
    
        The backup can then be used by a partner script to mirror GPOs in a test domain.
    
        Details:
        * Creates a XML file containing PSCustomObjects used by partner import script
        * Creates a XML file WMI filter details used by partner import script
        * Creates a CSV file of additional information for readability
        * Additional backup information includes SOM (Scope of Management) Path, Block Inheritance, Link Enabled,
          Link Order', Link Enforced and WMI Filter data
        * Each CSV SOM entry is made up of "DistinguishedName:BlockInheritance:LinkEnabled:LinkOrder:LinkEnforced"
        * Option to create a Migration Table (to then be manually updated)
    
        Requirements: 
        * PowerShell GroupPolicy Module
        * PowerShell ActiveDirectory Module
        * Group Policy Management Console
    
    .EXAMPLE
       .\BackUp_GPOs.ps1 -Domain wintiptoys.com -BackupFolder "\\wingdc01\backups\"
    
       This will backup all GPOs in the domain wingtiptoys.com and store them in a date and time stamped folder 
       under \\wingdc01\backups\.
    
    .EXAMPLE
       .\BackUp_GPOs.ps1 -Domain contoso.com -BackupFolder "c:\backups" -MigTable
    
       This will backup all GPOs in the domain contoso.com and store them in a date and time stamped folder 
       under c:\backups\. A migration table, MigrationTable.migtable, will also be created for manual editing.
    
    .OUTPUTS
       Backup folder name in the format Year_Month_Day_HourMinuteSecond
       GpoDetails.xml
       WmiFilters.xml
       GpoInformation.csv
       MigrationTable.migtable (optional)
    
       EXIT CODES: 1 - GPMC not found
    
    .NOTES
        THIS CODE-SAMPLE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR 
        FITNESS FOR A PARTICULAR PURPOSE.
    
        This sample is not supported under any Microsoft standard support program or service. 
        The script is provided AS IS without warranty of any kind. Microsoft further disclaims all
        implied warranties including, without limitation, any implied warranties of merchantability
        or of fitness for a particular purpose. The entire risk arising out of the use or performance
        of the sample and documentation remains with you. In no event shall Microsoft, its authors,
        or anyone else involved in the creation, production, or delivery of the script be liable for 
        any damages whatsoever (including, without limitation, damages for loss of business profits, 
        business interruption, loss of business information, or other pecuniary loss) arising out of 
        the use of or inability to use the sample or documentation, even if Microsoft has been advised 
        of the possibility of such damages, rising out of the use of or inability to use the sample script, 
        even if Microsoft has been advised of the possibility of such damages. 
    
    #>
    ##########################################################################################################
    
    #################################
    ## Script Options and Parameters
    #################################
    
    #Requires -version 3
    #Requires -modules ActiveDirectory,GroupPolicy
    
    
    #Define and validate parameters
    [CmdletBinding()]
    Param(
          #The target domain
          [parameter(Mandatory=$True,Position=1)]
          [ValidateScript({Get-ADDomain $_})] 
          [String]$Domain,
    
          #The backup folder
          [parameter(Mandatory=$True,Position=2)]
          [ValidateScript({Test-Path $_})]
          [String]$BackupFolder,
    
          #Whether to create a migration table
          [Switch] 
          $MigTable
          )
    
    
    #Set strict mode to identify typographical errors (uncomment whilst editing script)
    #Set-StrictMode -version Latest
    
    
    ##########################################################################################################
    
    ########
    ## Main
    ########
    
    ########################
    ##BACKUP FOLDER DETAILS
    #Create a variable to represent a new backup folder
    #(constructing the report name from date details and the supplied backup folder)
    $Date = Get-Date
    
    $SubBackupFolder = "$BackupFolder\" + `
                       "$($Date.Year)_" + `
                       "$("{0:D2}" -f $Date.Month)_" + `
                       "$("{0:D2}" -f $Date.Day)_" + `
                       "$("{0:D2}" -f $Date.Hour)" + `
                       "$("{0:D2}" -f $Date.Minute)" + `
                       "$("{0:D2}" -f $Date.Second)"
    
    
    ##################
    ##BACKUP ALL GPOs
    #Create the backup folder
    New-Item -ItemType Directory -Path $SubBackupFolder | Out-Null
    
    
    #Make sure the backup folder has been created
    If (Test-Path -Path $SubBackupFolder) {
    
        #Connect to the supplied domain
        $TargetDomain = Get-ADDomain $Domain
        
    
        #Obtain the domain FQDN
        $DomainFQDN = $TargetDomain.DNSRoot
    
    
        #Obtain the domain DN
        $DomainDN = $TargetDomain.DistinguishedName
        
    
        #Backup all the GPOs found in the domain
        $Backups = Backup-GPO -All -Path $SubBackupFolder -Domain $DomainFQDN -Comment "Scripted backup created by $env:userdomain\$env:username on $(Get-Date -format d)"
    
    
            #Instantiate an object for Group Policy Management (GPMC required)
            Try {
    
                $GPM = New-Object -ComObject GPMgmt.GPM
        
            }   #End of Try...
        
            Catch {
    
                #Display exit message to console
                $Message = "ERROR: Unable to connect to GPMC. Please check that it is installed."
                Write-Host
                Write-Error $Message
      
                #Exit the script
                Exit 1
        
            }   #End of Catch...
    
    
        #Import the GPM API constants
        $Constants = $GPM.getConstants()
    
    
        #Connect to the supplied domain
        $GpmDomain = $GPM.GetDomain($DomainFQDN,$Null,$Constants.UseAnyDc)
    
    
    
        ###################################
        ##COLLECT SPECIFIC GPO INFORMATION
        #Loop through each backed-up GPO
        ForEach ($Backup in $Backups) {
    
            #Get the GPO GUID for our target GPO
            $GpoGuid = $Backup.GpoId
    
    
            #Get the backup GUID for our target GPO
            $BackupGuid = $Backup.Id
            
    
            #Instantiate an object for the relevant GPO using GPM
            $GPO = $GpmDomain.GetGPO("{$GpoGuid}")
    
    
            #Get the GPO DisplayName property
            $GpoName = $GPO.DisplayName
    
                
                ##Retrieve SOM Information
                #Create a GPM search criteria object
                $GpmSearchCriteria = $GPM.CreateSearchCriteria()
    
    
                #Configure search critera for SOM links against a GPO
                $GpmSearchCriteria.Add($Constants.SearchPropertySOMLinks,$Constants.SearchOpContains,$GPO)
    
    
                #Perform the search
                $SOMs = $GpmDomain.SearchSOMs($GpmSearchCriteria)
    
            
                #Empty the SomPath variable
                $SomInfo = $Null
    
            
                    #Loop through any SOMs returned and write them to a variable
                    ForEach ($SOM in $SOMs) {
    
                        #Capture the SOM Distinguished Name
                        $SomDN = $SOM.Path
    
                    
                        #Capture Block Inheritance state
                        $SomInheritance = $SOM.GPOInheritanceBlocked
    
                    
                        #Get GPO Link information for the SOM
                        $GpoLinks = (Get-GPInheritance -Target $SomDN).GpoLinks
    
    
                            #Loop through the GPO Link information and match info that relates to our current GPO
                            ForEach ($GpoLink in $GpoLinks) {
    
                                If ($GpoLink.DisplayName -eq $GpoName) {
    
                                    #Capture the GPO link status
                                    $LinkEnabled = $GpoLink.Enabled
    
    
                                    #Capture the GPO precedence order
                                    $LinkOrder = $GpoLink.Order
    
    
                                    #Capture Enforced state
                                    $LinkEnforced = $GpoLink.Enforced
    
    
                                }   #End of If ($GpoLink.DisplayName -eq $GpoName)
    
    
                            }   #End of ForEach ($GpoLink in $GpoLinks)
    
    
                    #Append the SOM DN, link status, link order and Block Inheritance info to $SomInfo
                    [Array]$SomInfo += "$SomDN`:$SomInheritance`:$LinkEnabled`:$LinkOrder`:$LinkEnforced"
                
                
                    }   #End of ForEach ($SOM in $SOMs)...
    
    
            ##Obtain WMI Filter path using Get-GPO
            $WmiFilter = (Get-GPO -Guid $GpoGuid).WMiFilter.Path
            
            #Split the value down and use the ID portion of the array
            $WMiFilter = ($WmiFilter -split "`"")[1]
    
    
            #Add selected GPO properties to a custom GPO object
            $GpoInfo = [PSCustomObject]@{
    
                    BackupGuid = $BackupGuid
                    Name = $GpoName
                    GpoGuid = $GpoGuid
                    SOMs = $SomInfo
                    DomainDN = $DomainDN
                    WmiFilter = $WmiFilter
            
            }   #End of $Properties...
    
            
            #Add our new object to an array
            [Array]$TotalGPOs += $GpoInfo
    
    
        }   #End of ForEach ($Backup in $Backups)...
    
    
    
        #####################
        ##BACKUP WMI FILTERS
        #Connect to the Active Directory to get details of the WMI filters
        $WmiFilters = Get-ADObject -Filter 'objectClass -eq "msWMI-Som"' `
                                   -Properties msWMI-Author, msWMI-ID, msWMI-Name, msWMI-Parm1, msWMI-Parm2 `
                                   -ErrorAction SilentlyContinue
    
    
    
        ######################
        ##CREATE REPORT FILES
        ##XML reports
        #Create a variable for the XML file representing custom information about the backed up GPOs
        $CustomGpoXML = "$SubBackupFolder\GpoDetails.xml"
    
        #Export our array of custom GPO objects to XML so they can be easily re-imported as objects
        $TotalGPOs | Export-Clixml -Path $CustomGpoXML
    
        #If $WMIFilters contains objects write these to an XML file
        If ($WmiFilters) {
    
            #Create a variable for the XML file representing the WMI filters
            $WmiXML = "$SubBackupFolder\WmiFilters.xml"
    
            #Export our array of WMI filters to XML so they can be easily re-imported as objects
            $WmiFilters | Export-Clixml -Path $WmiXML
    
        }   #End of If ($WmiFilters)
    
    
        ##CSV report
        #Create a variable for the CSV file that will contain the SOM (Scope of Management) information for each backed-up GPO
        $SOMReportCSV = "$SubBackupFolder\GpoInformation.csv"
    
    
        #Now, let's create the CSV report 
        ForEach ($CustomGPO in $TotalGPOs) {
                
            #Start constructing the CSV file line entry for the current GPO
            $CSVLine = "`"$($CustomGPO.Name)`",`"{$($CustomGPO.GPOGuid)}`","
    
    
            #Expand the SOMs property of the current object
            $CustomSOMs = $CustomGPO.SOMs
    
    
                #Loop through any SOMs returned
                ForEach ($CustomSOM in $CustomSOMs) {
    
                    #Append the SOM path to our CSV line
                    $CSVLine += "`"$CustomSOM`","
    
             
               }   #End of ForEach ($CustomSOM in $CustomSOMs)...
    
    
           #Write the newly constructed CSV line to the report
           Add-Content -Path $SOMReportCSV -Value $CSVLine
    
    
        }   #End of ForEach ($CustomGPO in $TotalGPOs)...
    
    
        ###########
        ##MIGTABLE
        #Check whether a migration table should be created
        If ($MigTable) {
    
            #Create a variable for the migration table
            $MigrationFile = "$SubBackupFolder\MigrationTable.migtable"
    
            #Create a migration table 
            $MigrationTable = $GPM.CreateMigrationTable()
    
    
            #Connect to the backup directory
            $GpmBackupDir = $GPM.GetBackUpDir($SubBackupFolder)
    
    
            #Reset the GPM search criterea
            $GpmSearchCriteria = $GPM.CreateSearchCriteria()
    
    
            #Configure search critera for the most recent backup
            $GpmSearchCriteria.Add($Constants.SearchPropertyBackupMostRecent,$Constants.SearchOpEquals,$True)
       
    
            #Get GPO information
            $BackedUpGPOs = $GpmBackupDir.SearchBackups($GpmSearchCriteria)
    
    
                #Add the information to our migration table
                ForEach ($BackedUpGPO in $BackedUpGPOs) {
    
                    $MigrationTable.Add($Constants.ProcessSecurity,$BackedUpGPO)
            
                }   #End of ForEach ($BackedUpGPO in $BackedUpGPOs)...
    
    
            #Save the migration table
            $MigrationTable.Save($MigrationFile)
    
    
        }   #End of If ($MigTable)...
    
    
    }   #End of If (Test-Path $SubBackupFolder)...
    
    
    
    
    

    Friday, February 14, 2014 6:44 PM
  • Hi Tommy,

    I looked at the cmdlet myself and the -Name parameter accepts Pipiline input true (ByPropertyName), wouldnt this mean what Mike sugested above should in theory work?

    Thank you.

    Friday, February 14, 2014 6:52 PM
  • The -Name parameter is still only setup to take a single computer name, not multiple names. However, there is a way to accomplish what you're after by looping through your result set.

    $GPOs = Get-GPO -All | where {$_.DisplayName -like '*win7*'}
    
    
    foreach ($GPO in $GPOs) {
        Backup-GPO -Name $GPO.DisplayName -Path 'C:\GPO-Backup'
    }



    Friday, February 14, 2014 7:27 PM
  • This is unpolished, but it seems to do the trick:

    $GPOBackupPath = 'C:\GPOBackup' # This path MUST already exist or Backup-GPO will fail
    
    $GPONames = @"
    USER - Filtered Director User GPO
    USER - Base Exec User GPO
    USER - Base User Preferences GPP
    SVR - Base GPO
    WKS - Base Desktop GPO
    "@
    
    $splitGPO = ($GPONames -split "`n").Trim()
    
    $filteredGPOList = @()
    
    Get-GPO -All | ForEach {
    
        If ( $splitGPO -contains $_.DisplayName ) { $filteredGPOList += $_ }
    
    }
    
    Write-Host 'GPO List:'
    $filteredGPOList | Select DisplayName
    
    $ans = Read-Host 'Back up these GPOs?'
    
    If ($ans.ToUpper() -eq 'Y') { $filteredGPOList | Backup-GPO -Path $GPOBackupPath }

    Set the $GPOBackupPath and adjust the $GPONames variable (one GPO name per line).


    Don't retire TechNet! - (Don't give up yet - 12,575+ strong and growing)

    Friday, February 14, 2014 7:47 PM
    Moderator
  • Hi Tommy,

    This works well and does exactly what I need, I just finished testing it. However 1 minor detail is missing, with your modifications my GpoDetails.xml file that is generated is empty. If I remove your modifications the script generates the GpoDetails.xml file and populates it with relevant GPO info.

    This file is crucial to restore the backedup Gpo's.

    Would you happen to know why the file wont get populated?

    Also, the GpoInformation.csv file is not generated at all, mostly due to an empty GpoDetails.xml. PowerShell doesnt give me any relevant error messages but file not found.




    • Edited by Mustafa-s Friday, February 14, 2014 9:28 PM
    Friday, February 14, 2014 7:57 PM
  • I think I'm no longer putting the result in the $Backups variable, so the following loop (ForEach ($Backup in $Backups) - line 178) never gets executed..

    Would there be an easy fix to this?

    Friday, February 14, 2014 9:39 PM
  • Hi Mustafa-s,

    Please try the script below and feedback, which make a little modification:

    $Backups=get-gpo -all | where{$_.DisplayName -like '*win7*'}| foreach {
    backup-gpo $_.displayname -Path $SubBackupFolder -Domain $DomainFQDN -Comment "Scripted backup created by $env:userdomain\$env:username on $(Get-Date -format d)"
    }

    Best Regards,

    Anna

    Tuesday, February 18, 2014 6:21 AM
    Moderator