How to Back Up All GPOs in a Domain

This article illustrates using the Group Policy Management Console (GPMC) Class Library to back up Group Policy objects (GPOs) to a specified folder. The first section details step-by-step instructions on implementing the code, while the example that follows is a working Visual C# console application that can be modified to fit your specific needs.

To back up a domain’s GPOs

  1. Add the Microsoft.GroupPolicy.Management assembly to your project.

  2. Insert a using directive for the Microsoft.GroupPolicy namespace.

    using Microsoft.GroupPolicy;
    
  3. Instantiate a GPDomain object representing the domain whose Group Policy objects (GPOs) will be backed up. The following code snippet shows two different ways of instantiating a GPDomain object. The first example calls the default GPDomain constructor, which takes no parameters and uses the domain of the current user. The second example shows a hard-coded value being passed as the domain name that will be used in the construction of the GPDomain object.

    // Use current user’s domain 
    GPDomain domain = new GPDomain();
    
    // Use supplied domain name 
    GPDomain domain = new GPDomain("MyDomain");
    
  4. Call the GPDomain object’s GetAllGPOs method. This method will return a GpoCollection object containing all the Group Policy objects (GPOs) in the domain.

    // Get all GPOs in domain (returned in a GpoCollection)
    GpoCollection gpos = domain.GetAllGpos();
    
  5. After you have the GpoCollection, implement a foreach loop to iterate over the collection of Group Policy objects (GPOs).

    foreach (Gpo currentGpo in gpos)
    {
      ...
    }
    
  6. For each GPO object, call its Backup method passing two parameters: the directory into which you want the backed up GPO to reside and a comment.

    currentGpo.Backup(@"C:\GPOBackups", "Comment");
    

Example

The following is the complete code listing for a console application that backs up all of the GPOs in a specified domain.

/*----------------------------------------------------------------------
This file is part of the Microsoft Windows Server Update Services
API Code Samples.

DISCLAIMER OF WARRANTY: THIS CODE AND INFORMATION ARE PROVIDED "AS-IS."  
YOU BEAR THE RISK OF USING IT.  MICROSOFT GIVES NO EXPRESS WARRANTIES, 
GUARANTEES OR CONDITIONS.  YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS 
UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE.  
TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES 
THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
PURPOSE AND NON-INFRINGEMENT.
----------------------------------------------------------------------*/
using System;
using Microsoft.GroupPolicy;

/*
 * Purpose: This sample illustrates how to use the GPMC Class Library to back up 
 * all GPOs of a specified (or current) domain to the specified folder.
 * Syntax: BackupGPOs /f backupFolder [/d domainName] [/c comment]
 * (Note that the doman defaults to the current domain if one is not specified.)
 */

namespace BackupGPOs
{
  class Program
  {
    static void Main(string[] args)
    {
      Program program = new Program();
      program.Run(args);
    }

    // Initialize variables to track successful and failed backups
    int nSuccesses = 0;
    int nFailures = 0;

    // Variables obtained from user-supplied parameters and used for the backup procedure
    GPDomain domain;
    string domainName;
    string backupFolder;
    string backupComment;

    void Run(string[] args)
    {
      try
      {
        InitUI();
        if (ParseParameters(args))
        {
          SetDomainObject();
          BackupAllGPOs();
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
      finally
      {
        PrintSummary();
      }
    }

    void InitUI()
    {
      // Clear console and output what we're doing
      Console.Clear();
    }

    bool ParseParameters(string[] args)
    {
      // We need at least the /f or /? param
      if (args.Length < 2) 
      {
        return PrintSyntax();
      }

      // Check for syntax help request
      if (Array.IndexOf(args, "/?") != -1)
      {
        return PrintSyntax();
      }

      // Directory (/f) parameter MUST be passed
      int idx;
      if ((idx = Array.IndexOf(args, "/f")) != -1)
      {
        // backup backupFolder/folder specified
        this.backupFolder = args[idx + 1];
      }
      else
      {
        return PrintSyntax();
      }

      // Get the backup comment. If not supplied, we will pass a blank comment when backing up the GPOs
      this.backupComment = String.Empty;
      if ((idx = Array.IndexOf(args, "/c")) != -1)
      {
        // Save the user-specified comment for later use when backing up the GPOs
        this.backupComment = args[idx + 1];
      }

      // Get the domain name. If not supplied, we will use the current domain
      this.domainName = String.Empty;
      if ((idx = Array.IndexOf(args, "/d")) != -1)
      {
        // Save the user-specified domain name for later use in instantiating the GPDomain object
        this.domainName = args[idx + 1];
      }

      return true; // successful parsing
    }

    bool PrintSyntax()
    {
      Console.WriteLine("Syntax: BackupGPOs /f backupFolder [/d domainName] [/c comment]\r\n" + 
                        "(Note that the doman defaults to the current domain if one is not specified.)");
      return false; // if we got here the command line parsing failed
    }

    void SetDomainObject()
    {
      // Get a GPDomain object
      Console.WriteLine("Connecting to domain '{0}'",
                        (domainName.Length > 0) ? domainName : "[default domain]");
      if (domainName.Length > 0)
      {
        this.domain = new GPDomain(domainName);
      }
      else
      {
        this.domain = new GPDomain();
      }
      Console.WriteLine("Successfully connected to domain");
    }

    public void BackupAllGPOs()
    {
      try
      {
        // Initialize the Domain object
        Console.WriteLine("*** BackupGPOs: Processing all GPOs in domain '{0}' ***\n", this.domain.DomainName);

        // Get all GPOs in domain (returned in a GpoCollection)
        GpoCollection gpos = domain.GetAllGpos();

        // For each GPO in the domain...
        foreach (Gpo currentGpo in gpos)
        {
          Console.WriteLine();
          try
          {
            Console.Write("Processing '{0}'...", currentGpo.DisplayName);
            Console.Write("Backing up...");

            // Back up the current GPO
            currentGpo.Backup(this.backupFolder, this.backupComment);
            Console.WriteLine("Successful");

            // Increment our successes
            nSuccesses++;
          }
          catch (Exception ex)
          {
            Console.WriteLine("!!!FAILED!!!\r\nException: {0}\r\n", ex.Message);

            // Increment the failures
            nFailures++;
            
            // Continue with next GPO in the collection
            continue;
          }
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine("Exception caught:\r\n{0}\r\nStack:\t{1}",
                          ex.Message,
                          ex.StackTrace);
      }
    }
    
    public void PrintSummary()
    {
      // Print the count of successes and failures
      Console.WriteLine("\nBackup Summary: {0} Successful , {1} Failed",
                        nSuccesses, nFailures);
    }
  }
}