Bulk Import of Group Policy Objects between Different Domains with PowerShell

I’ve often worked with administrators who needed to duplicate an existing environment’s set of Group Policy Objects (GPO’s) to either a lab or other production domain. The challenge with that task is the source domain GPO’s typically have domain-specific values included in them such as users and groups identified in the User Rights Assignment section of multiple GPO’s and WMI filters linked to various GPO’s. Typically, none of those values exist in the destination domain, so administrators are forced to either modify every GPO, as a post-import process, or re-create respective users, groups, and WMI filters in the destination domain and manually update a Migration Table. An example of how to use a Migration Table can be found at https://technet.microsoft.com/en-us/library/cc781458(WS.10).aspx. This blog is going to provides examples of how to use PowerShell to automate the Migration Table mapping process and perform a bulk import of GPO’s along with their WMI filters.

As with any other import process of GPO’s and WMI filters into a new or existing Active Directory domain, we must first begin with an export from the source domain. PowerShell scripts to perform bulk exporting and importing WMI filters are available in an earlier blog of mine called Exporting and Importing WMI Filters with PowerShell. Exporting GPO’s is already automated within the Group Policy Management Console (GPMC), so I won’t cover those steps. If you need a review of exporting GPO’s with GPMC, you can find it on TechNet at https://technet.microsoft.com/en-us/library/cc781458(WS.10).aspx). When performing a backup of all GPO’s from the source domain, ensure the destination is set to an empty folder, so there is only one version of each GPO from the source domain in the backup folder. The last piece of the puzzle needed before the scripts come into play is a Migration Table file. The Migration Table file editor is described https://technet.microsoft.com/en-us/library/cc779961(WS.10).aspx. The option we’ll need as output can be created using the “Tools | Populate from Backup” feature from the menu bar of the Migration Table editor (mtedit.exe). Once a copy of the source GPO’s, a Migration Table XML file, and the WMI filters is available, they need to be moved over to the destination domain.
In the destination domain, it’s time for PowerShell to get to work. The PowerShell scripts described below can be found as attachments to this blog. Each script will perform a single step of the import process. The three steps from a high level are as follows:

  1. Create objects in the destination domain and update the Migration Table XML file.
  2. Import the GPO’s into the destination domain
  3. Link WMI filters to the new GPO’s previously joined to the source domain GPO’s

Step 1 is handled by the script called “CreateObjectsFromMigrationTable.ps1.” This script does exactly what its name indicates and more. When running the script, there is only one required parameter: $MigrationTable. That parameter specifies the location of the Migration Table that will be used during the GPO import. Right about now, I can hear some of you asking, “Do I still have to update that Migration Table file? It’s such a pain!” The answer is, “No!” When the “CreateObjectsFromMigrationTable.ps1” is run, it automatically updates the destination elements in the Migration Table file while creating domain objects identified from the source domain in the target domain. For example, if a group named “%source_domain%\Auditors” was used for the User Rights Assignment called “Manage auditing and security log,” the script would create an identically-named group in the destination domain called “%destination_domain%\Auditors” and update the Migration Table XML file with the new value. The scripts can handle users, groups of any type (e.g. Universal, Global, Domain Local), and computer objects. Finally, the script creates a log file that can be reviewed for objects created and other values the script does not currently handle (e.g. UNC paths used in the source GPO’s). The updated Migration Table file can now be used by a GPO import.

Step 2 is handled by a second script called “ImportAllGPOsFromBackup.ps1.” This script requires two parameters: $MigrationTable and $BackupLocation. The $MigrationTable parameter should be set to the new Migration Table XML file created by the first script. The $BackupLocation parameter should be set to the folder location containing the GPO backups. When this script runs, it uses the $MIgrationTable file to import all the GPO’s from the $BackupLocation. It does have limited error checking, so if a GPO already exists  in the destination domain with the same name as a GPO being imported, the imported GPO name is prepended with the string “DuplicateGPOOnImport –“ making the duplicate-named GPO’s easy to identify after the import is complete. This script  also creates a log file of its activity.

Step 3, the final script, is called “Set-WMIFilterLinks.ps1” and automatically links any WMI filter that was previously linked to the GPO in the source domain to the new GPO in the destination domain. For example if a GPO from the source domain had a WMI filter linked to it called “Windows Server 2008” the new GPO in the destination domain will have the same WMI filter linked to it. In order for this script to work, WMI filters with the same name as the source domain filters must exist in the destination domain. You can achieve that configuration using the scripts from my earlier blog: called Exporting and Importing WMI Filters with PowerShell. This script  also creates a log file of its activity.

That does it for the bulk import of GPO’s from one domain to another. The scripts could also be used to perform a recovery of GPO’s and WMI filters, but that situation is probably not as commonly needed. Also, please note that none of the actually GPO links to Sites, Domain, or Organizational Units (OU’s) will be persevered. A tool that does that would require quite of bit of code unless the Sites and OU structures were already in sync or made to be in sync between the source and destination domains.

Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use .

Bulk_Import_of_GPOs_Between_Domains_PowerShell_Scripts.zip

Comments

  • Anonymous
    January 01, 2003
    Mac, I'm glad it worked out for you. If you have any advice or lessons learned from your experience, please post them. Not sure what you mean by "Oh and SPIG, but first?" Thank you for the great comment!

  • Anonymous
    January 01, 2003
    007, The only parameter you need to provide is -BackupLocation. That parameter should be set to the path containing a Backup of the GPOs from the source domain that has been copied to the Destination domain. I'll add a check to the script to verify that parameter is set. thanks!

  • Anonymous
    January 01, 2003
    There is only one required parameter: $MigrationTable Syntax: CreateObjectsFromMigrationTable.ps1 -MigrationTable "<path_to_migtable>" Example: CreateObjectsFromMigrationTable.ps1 -MigrationTable "C:Tempmymigtable.migtable" You can also provide two other parameters (not required). The other parameters are "LogFile" and "Description." The LogFile parameter allows you to specify the location where the log file will be stored. The Description parameter allows you to set a custom description on all objects created in Active Directory (which makes them easier to find/sort after they are created and you want to relocated them." By default, the LogFile location is set to "C:MigrationTableLogFile.txt" and the Description is set to "This object was created by the CreateObjectsfromMigrationTable.ps1 script. It may need to be renamed." Once you run the script, review the Log File and maitain the modified versino of you Migration Table file. The new destination objects will automatically be updated to reflect the newly created objects and can be used with the "ImportAllGPOsFromBackup.ps1" script.

  • Anonymous
    January 01, 2003
    The comment has been removed

  • Anonymous
    January 01, 2003
    Tariq,

    Please try this post: http://blogs.technet.com/b/ashleymcglone/archive/2011/01/19/finally-copy-and-merge-gpos-powershell-saves-the-day.aspx

    Pay close attention to the "Limitations" section in case any of those limitations affect your policies.

    Manny

  • Anonymous
    January 01, 2003
    The comment has been removed

  • Anonymous
    January 01, 2003
    No. It's difficult to carry over links since they depend on OU structure. If you bring over WMI filters, the links for those WMI filters to GPO’s  can be automated with the scripts, but they the WMI filters in the destination domain have to be named exactly the same as they were in the source domain. The scripts provided in my blogs about Exporting and Importing WMI filters will handle that automation.

  • Anonymous
    January 01, 2003
    I'm swamped right now, but I'll take a look at it when I can. In the meantime, check out the Active Directory and Group Policy cmdlets for PowerShell: Active Directory: technet.microsoft.com/.../dd378937(v=WS.10).aspx Group Policy: technet.microsoft.com/.../ee461027.aspx Those modules ("activedirectory" and "grouppolicy") should be able to help accomplish the task you want to automate.

  • Anonymous
    June 06, 2012
    Can you give me an example for the PS command with the file needed please: CreateObjectsFromMigrationTable.ps1 $MigrationTable. CreateObjectsFromMigrationTable.ps1 migrationtable

  • Anonymous
    June 06, 2012
    Thanks for the response! Does your PS link GPOs as well?

  • Anonymous
    June 06, 2012
    My destination AD OU structure is exactly the same as my source AD structure.  I would like to create a script to import the same exact GPOs linked in my Target as they exist in my SOURCE.   Can you please help? Enrico

  • Anonymous
    February 20, 2013
    Hi, does this process work between two forest with the same FQDN ? Tks.

  • Anonymous
    August 15, 2013
    What parameter is needed for Set-WMIFilterLinks.ps1?

  • Anonymous
    November 15, 2013
    I used "Backup All..." in source domain, then copy the backup folder to target domain. But the "importAllGPOsFromBackup.ps1" didn't like it with error message below for each GPO. As a result empty GPOs are created. What did I do wrong? ==================== error msg ==================== Import-GPO : The system cannot find the file specified. (Exception from HRESULT: 0x80070002) At C:tempImportAllGPOsFromBackup.ps1:44 char:19

  •         import-gpo <<<<  -BackupGPOName $GPO.GPODisplayName."#cdata-section" -TargetName $GPO.GPODisplayName. =================================================
  • Anonymous
    November 15, 2013
    Also the migration table didn't seem to have been updated by the createObjectFromMigrationTable script

  • Anonymous
    November 15, 2013
    The comment has been removed

  • Anonymous
    November 15, 2013
    John, Regarding the Migration Table file specifically, there may be no need for it to be updated depending on the contents of the original file. Check the log file created by the script for any error or informational messages regarding the objects that exist in the source file.

  • Anonymous
    December 04, 2013
    Hi Everyone, I have a lot of policies which were created for Windows XP using the ADM templates and all these policies are consuming 4+MB space in SYSVOL folder. Is there any automated way to convert those polices to new ADMX format without recreating?

  • Anonymous
    January 23, 2014
    I'm moving GPOs from one child domain to another child domain. If I am using an EA account how do I ensure the create step goes to the correct child domain?

  • Anonymous
    January 23, 2014
    I should add that I am on a admin workstation and restricted to running admin controls there vs directly on the domain controller. Is there a way to specify a specific target domain.

  • Anonymous
    March 08, 2014
    The comment has been removed

  • Anonymous
    July 02, 2014
    The comment has been removed

  • Anonymous
    September 08, 2014
    Hello Manny Murguia,

    i have a question if you please answer me i will be thankful.my question is can we import specific GPO setting to an existing GPO. i mean a kind of Merge if the Existing GPO already contain some configuration i.e i want to only import the user configuration from a backup and i want the existing computer configuration remain there in its place .so user configuration and computer configuration of two different GPOs merge in one Gpo.

    thank you!

  • Anonymous
    March 10, 2015
    The comment has been removed

  • Anonymous
    July 27, 2015
    The comment has been removed

  • Anonymous
    October 08, 2015
    “GPO Bulk Export and Import to another Domain"

    Hy Manny, you can add my Solution for LABs, it is very quicky ..

    I’ve often worked with administrators who needed to duplicate an existing environment’s set of Group Policy Objects (GPO’s) to either a lab or other production domain. I write a script for Quick and Dirty “GPO Bulk Export and Import to another Domain”.

    http://www.brauckmann.ch/quick-and-dirty-gpo-bulk-export-and-import-to-another-domain

    # Quick and Dirty "GPO Bulk Import Script to another Domain"
    # Prefine GPO Source path

    $path = "C:Gpo-Import-B"
    $file = Get-ChildItem -Path $path -include gpreport.xml -Recurse

    # At the Windows PowerShell prompt, type Import-Module GroupPolicy –verbose
    Write-Output "Import-Module -Name grouppolicy –verbose"

    foreach ($xmlFile in $file){
    $part = $xmlFile | % { Split-Path (Split-Path $_.fullname -Parent) -Leaf }

    $MyXml = [xml](Get-Content $xmlFile)

    $output = "import-gpo -BackupId "
    $output += $part.Replace("{","}").Replace("}","")
    $output += " -TargetName &quot;&quot;<br>$output &#43;= $MyXml.GPO.Name<br>$output &#43;= &quot;" -path "
    $output += $path
    $output += " -CreateIfNeeded"

    Write-Output $output
    }

    Here ist the output Script Example:

    PS C:Gpo-Import-Bimport-gpo.ps1
    Import-Module -Name grouppolicy –verbose
    import-gpo -BackupId 065D10CE-1FF5-4B44-BA85-94544DDF0771 -TargetName "All - Citrix Settings" -path C:Gpo-Import-B -CreateIfNeeded
    import-gpo -BackupId 083523B4-AC6A-4E4B-B88F-0C14A5636538 -TargetName "User - Applikation Settings" -path C:Gpo-Import-B -CreateIfNeeded
    import-gpo -BackupId 097907E0-323F-49D6-BF25-F8F95ADBF6B3 -TargetName "Computer - AD Audit PlusPolicy" -path C:Gpo-Import-B -CreateIfNeeded
    import-gpo -BackupId 0D5DE211-A00A-488F-A311-FDCAE871D987 -TargetName "All - Workstation Settings" -path C:Gpo-Import-B -CreateIfNeeded
    import-gpo -BackupId 0E619FF2-80BD-46D2-934F-0202080DCBDF -TargetName "User - XD7 KioskMode" -path C:Gpo-Import-B -CreateIfNeeded

    ------------------------------------------------------
    cu Andreas Brauckmann