Downloads
40231.zip

The Microsoft Management Console (MMC) Group Policy Management Console (GPMC) snap-in is an exceptionally helpful new tool in Windows Server 2003. GPMC lets you perform most Group Policy Object (GPO)—related tasks from one interface. Even better, GPMC installs several COM objects that you can use to automate most of these tasks. In "Scripting Group Policy Objects" (October 2003, http://www.winscriptingsolutions.com, InstantDoc ID 39856), I discussed how to get started using these objects. That article, as well as the other resources I've listed in "Related Resources," page 2, can teach you the basics of how to automate policy-based tasks. With the basics under your belt, you're ready to start using GPMC's COM objects for bigger and better tasks, such as programmatically searching for GPOs, finding all the Scope of Management (SOM) objects for a GPO, and finding all the SOM objects in an Active Directory (AD) tree.

A Simple Search for All GPOs
To use the scripts in "Scripting Group Policy Objects," you must know the globally unique identifier (GUID) of the GPO to which you want to connect in AD. The parts of the GPO that AD stores have a distinguished name (DN) such as cn=\{myguid\}, cn=policies, cn=system, dc=mydomain, dc=mycorp, dc=com, where \{myguid\} is the GUID. In theory, using the GUID isn't a problem because GPOs tend to change little after administrators have set them up. But what if you don't want to hard-code the GUID in the script? Or what if you want to find out which GPOs exist in AD or which GPOs are linked to a specific SOM object? In such cases, you can automate searches within GPMC.

For example, the script SearchAndReport.vbs, which Listing 1, page 2, shows, searches the specified domain for all GPOs that exist, whether or not they're linked to an AD tree. The script begins by setting the DOMAIN constant to the name of the domain to search. If you want to use SearchAndReport.vbs, you must replace mydomain.mycorp.com with the name of your domain. This same holds true for all the constants in the scripts I present here. You need to replace the values that are being assigned to those constants with values that apply to your AD.

In the code at callout A in Listing 1, I use VBScript's CreateObject function to create a reference to the GPM object. I use the GPM object's GetDomain method with the DOMAIN constant as an argument to create a GPMDomain object that represents my domain. This GPMDomain object will let me create, query, and restore GPOs and search SOM objects in that domain. I also use the GPM object's CreateSearchCriteria method to create a reference to a GPMSearchCriteria object. You can use this object to specify the criteria for your search operation. In this case, I haven't specified any criteria—in other words, I passed in a "blank" GPMSearchCriteria object—which will prompt the retrieval of all the GPOs in the domain.

With the necessary objects in hand, I execute the search. As the code at callout B in Listing 1 shows, I use the GPMDomain object's SearchGPOs method with a blank GPMSearchCriteria object as the parameter. The SearchGPOs method returns a GPMGPOCollection object that contains all the GPOs in the domain. I then work with that collection in the usual manner. I start by using the GPMGPOCollection object's Count property to count the number of GPOs in the collection, then use the Echo command to display that number. Next, I use a For Each...Next statement to walk through the collection. For each GPO, I display the GPO's GUID, friendly display name, and DN. The GUID and the DN are both unique because they both contain the GUID. The display name doesn't have to be unique.

Finding SOM Objects for a GPO
As SearchAndReport.vbs demonstrates, searching a domain for all the GPOs it contains is simple. Let's now look at a more complicated search. Suppose you want to find all the domains and organizational units (OUs) that a GPO links to in the AD tree. In other words, suppose you want to find all the domain and OU SOM objects for a GPO. You can use a script such as FindSOMsforGPO.vbs, which Listing 2 shows. This script uses a known GPO as the basis for the search; a constant represents the GPO's GUID. The GUID in FindSOMsforGPO.vbs is the Default Domain Policy object's GUID, which is the same across all Windows 2003 and Windows 2000 Server domains. By using this GUID, you can run FindSOMsforGPO.vbs and discover all the domains and OUs to which the Default Domain Policy links.

Let's discuss how FindSOMsforGPO.vbs works. In the code at callout A in Listing 2, I create a reference to the GPM object and use that object's GetDomain method to create a GPMDomain object. Using the GPMDomain object's GetGPO method with the GUID constant as an argument, I retrieve the GPO that represents the Default Domain Policy.

Next, I need to search the domain for any SOM objects that use the same GUID as the defined GUID constant. To do this, I can use the GPMDomain object's SearchSOMs method to return a GPMSOMCollection object, which represents a collection of SOM objects. The SearchSOMs method requires a GPMSearchCriteria object as a parameter. However, if I pass in a blank GPMSearchCriteria object, as I did in Listing 1, I'll get all the SOM objects for the domain—and that's not what I want. Instead, I want to retrieve the SOM objects for only one specific GPO. To ensure that the search returns only those SOM objects, I need to add to the GPMSearchCriteria object a criterion that specifies the GPO in which I'm interested.

As the code at callout B in Listing 2 shows, I first create a GPMSearchCriteria object, as I did in Listing 1. Next, I need to use the GPMSearchCriteria object's Add method to add a criterion to the object.

In the Microsoft Developer Network (MSDN) Library, the syntax for the Add method might look complex, but the method is easy to use. To add criteria, you use the syntax

Add(SearchProperty,
SearchOperator, Value)

where SearchProperty and Value specify the property name and value, respectively, that you want to search for and where SearchOperator specifies the operator you want to use to conduct that search. The Add method includes operators that let you find a property that contains (opContains), doesn't contain (opNotContains), equals (opEquals), or doesn't equal (opNotEquals) a value. For example, if I'm searching for a specific GPO in the domain with a known GUID, I can use

gpoID opEquals GUID

In other words, I'm looking for the gpoID property whose value is equal to the GUID constant's value.

The great news about specifying search criteria is that whichever GPM object search method receives the GPMSearchCriteria object as a parameter tends to dictate exactly what criteria you can use. This constraint helps enormously. In this case, I want to use the SearchSOMs method to search the domain for SOM objects and I want to limit the results to my GPO's GUID. According to the documentation for the GPMDomain object's SearchSOMs method in "Group Policy Management Console Reference" (http://msdn.microsoft.com/library/default.asp?url=/library/enus/gpmc/gpmc/group_policy_management_console_reference.asp), I can use only the somLinks search property. According to the documentation for the GPMSearchCriteria object's Add method, the somLinks search property can use only the opContains search operator and the value must be a GPMGPO object. Thus, I must add a criterion that states the SOM links (somLinks) must contain (opContains) my GPO.

So, as the code at callout B shows, after creating a blank GPMSearchCriteria object, I use the Add method to add the criterion. As I mentioned earlier in the article, the Add method takes three parameters: SearchProperty, SearchOperator, and Value. Because the SearchProperty and SearchOperator parameter values are constants—somLinks and opContains, respectively—I dynamically pass in these two constants rather than hard-coding them in the script. As I explained in "Scripting Group Policy Objects," you first need to connect to the GPMConstants object to dynamically pass in constants. After making that connection and assigning the reference to the gpmConstants variable, I specify gpmConstants.SearchPropertySOMLinks for the SearchProperty parameter and gpmConstants.SearchOpContains for the SearchOperator parameter. For the Value parameter, I simply need to specify the gpmGPO variable because that variable holds the GPO object to which I want to connect. Finally, I execute the SearchSOMs method and assign the results to a variable named colDOUSOMs, which is a GPMSOMCollection object. The colDOUSOMs variable contains a collection of SOM objects that represent the domain and its OUs to which my GPO links. The code at callout C in Listing 2 displays the number of SOM objects, then displays each SOM object's path.

Finding All SOM Objects
Rather than constraining the search by finding domain and OU SOM objects for a specific GPO, let's search for and list all the sites, domains, and OUs in the AD tree that have GPOs linked to them. As you already know, you can use the GPMDomain object's SearchGPOs method with a blank GPMSearchCriteria object to list all GPOs. Because you can use the GPMSearchCriteria object with the GPMSitesContainer's SearchSites method and the GPMDomain object's SearchSOMs method, you would logically think that you could use a blank GPMSearchCriteria object to receive all the SOM objects relating to sites and all the SOM objects relating to domains and OUs, respectively. Counterintuitively, these methods don't work that way. You absolutely must supply a criterion to the GPMSearchCriteria object when you use this object with the SearchSites and SearchSOMs methods; otherwise, you'll get an error.

You have two options for how to list all the sites, domains, and OUs in the AD tree that have GPOs linked to them. You can use a script such as ListSOMPolicyTree.wsf to walk through AD. (You can find this script in C:\program files\gpmc\scripts directory after installing GPMC.) Or you can use the script FindAllSOMs.vbs, which Listing 3 shows, to retrieve all the GPOs, then find the SOM objects for those GPOs.

FindAllSOMs.vbs starts by creating connections to the GPMDomain and GPMConstants objects. Next, FindAllSOMs.vbs uses the same code as SearchAndReport.vbs to retrieve the GPMGPOCollection object, which holds the collection of GPOs to iterate through. However, unlike SearchAndReport.vbs, FindAllSOMs.vbs explicitly clears the gpmSearchCriteria variable by setting it to Nothing, as the code at callout A in Listing 3 shows. I cleared this variable because the script later reuses it. Although you aren't required to explicitly clear a variable before reusing it, doing so makes the script easy to modify at a later date if needed.

Now that I have the collection of GPOs, I use a For Each...Next loop to iterate through them. After I display some details about the current GPO in the loop, I create another GPMSearchCriteria object, set it to the cleared gpmSearchCriteria variable, and add a criterion that specifies the current GPO. That way, I can use the GPMDomain object's SearchSOMs method to retrieve a collection of SOM objects for this specific GPO. After clearing the gpmSearchCriteria variable again in preparation for the next iteration of the loop, I display the details relating to each individual SOM object. For each SOM object, I display the name rather than the path, as I did in FindSOMsforGPO.vbs.

As the code at callout B in Listing 3 shows, I then use a Select Case statement and the GPMConstants object to determine whether the SOM object is a site, a domain, or an OU. After making this determination, the Select Case statement displays the type of the SOM object after the SOM object's name.

Finally, I use the GPMSOM object's Path method to obtain each SOM object's path and the GPMSOM object's GetGPOLinks method to get each SOM object's GPO links. A GUID represents each link, and I include the link order (i.e., specify the order in which the links are applied). To make this link information easier to read, I format the text with line returns (i.e., vbCrLf) and tabs (i.e., vbTab).

Listing 3 works best if you use cscript.exe to run the script from the command line. The outputted text scrolls much more effectively.

Run the Scripts and Experiment
You now know how to script simple and some complex GPMC searches. If you want to use the three scripts I've shown you, simply customize the values assigned to the scripts' constants, open the command-shell window, and use the following commands to launch the scripts:

cscript.exe SearchAndReport.vbs
cscript.exe FindSOMsforGPO.vbs
cscript.exe FindAllSOMs.vbs

In addition, I encourage you to take a look through "Group Policy Management Console Reference" and experiment with scripting your own GPMC searches and other policy-based tasks.

Related Resources
WINDOWS SCRIPTING SOLUTIONS ARTICLE
Alistair G. Lowe-Norris, "Scripting Group Policy Objects,"
October 2003, http://www.winscriptingsolutions.com, InstantDoc ID 39856

MICROSOFT ARTICLES
"Enterprise Management with the Group Policy Management Console"
http://www.microsoft.com/windowsserver2003/gpmc

"Group Policy Management Console Reference"
http://msdn.microsoft.com/library/default.asp?url=/
library/en-us/gpmc/gpmc/group_policy_
management_console_reference.asp

BOOK
Robbie Allen and Alistair G. Lowe-Norris,
Active Directory, 2nd edition, "Chapter 7:
Profiles and Group Policy Primer" and "Chapter 10:
Designing Organization-Wide Group Policies" (O'Reilly
and Associates, 2003)