Retrieving Permissions for a GPO

Applies To: Windows Server 2003, Windows Server 2003 R2, Windows Server 2003 with SP1, Windows Server 2003 with SP2

The script in Listing 2, GetGPOPerms.vbs, demonstrates how to use several GPMC objects to list the permissions for a GPO in a test domain. GetGPOPerms.vbs begins by instantiating the GPM and GPMConstants objects. Next, the script accesses IGPMDomain, a useful interface that lets you retrieve information about a domain and manage GPOs within it. To access IGPMDomain, you use the GPM object's GetDomain method, which returns a GPMDomain object. As callout A in Listing 2 shows, the GetDomain method takes three arguments. The first argument is the name of the domain that stores the GPOs you want to manage. The domain name must be the domain's DNS name (e.g., mycompany.net). As callout A shows, you can hard-code this argument's value in the script. Another approach is to have the scripts' users provide the domain name at the command line when they launch the script.

The second argument lets you specify which domain controller (DC) you want to use to connect to the domain. A null string ("") signifies that you don't have a DC preference, which means that the GetDomain method will use the PDC emulator. For the third argument, you specify the option you want to use to find a DC with which to connect. You have three options: GPM_USE_ANYDC, (use any available DC), GPM_USE_PDC (use the PDC emulator DC), or GPM_DONOTUSE_W2KDC (use a DC running Windows 2003). As callout A shows, GetGPOPerms.vbs uses the GPMConstants object's UseAnyDC property to specify the GPM_USE_ANYDC option.

After you connect to the domain, the real fun starts. As the code at callout B in Listing 2 shows, you use the GPMDomain object's GetGPO method to retrieve the GPMGPO object that represents the GPO for which you want to list the permissions. To use GetGPOPerms.vbs, you need to replace the domain name mycompany.net with the DNS name of your AD domain. Notice that the GetGPO method's argument is the GPO's globally unique identifier (GUID) and not the GPO's friendly name. In this script, I included the GUID for the Default Domain Policy that's present in every AD domain. This GUID is the same for all AD domains.

If the scripts' users will be providing the necessary GPO information at the command line, having them input the hard-to-type GUID might not be an option. An alternative is to have the users provide the GPOs' friendly names; you can then obtain the corresponding GUID by using the GetGPObyName function, which Microsoft provides in the lib_commongpmcfunctions.js file in the Scripts folder. GetGPObyName uses the IGPMSearchCriteria interface to search all the GPOs in a domain and, on matching the friendly name entered, returns a GUID that the script can pass to GetGPO. However, GetGPObyName is a JScript function. If you'd rather use VBScript, you can write a VBScript version of GetGPObyName or use the GetGPOs, GPOName, and GPOGuid methods in the IADsTools COM object, which is part of the Windows 2000 Support Tools. For more information about these methods, see the article "Scripting with IADsTools," April 2003, https://www.windowsitpro.com, InstantDoc ID 38286.

Next, the script uses the GPMGPO object's GetSecurityInfo method to retrieve the permissions for the GPO. The GetSecurityInfo method returns a reference to a GPMSecurityInfo collection object, which the script assigns to the GPOSec variable. The GPMSecurityInfo object contains the set of permissions assigned to the GPO. The script then iterates through the collection and uses the GPMSecurityInfo object's Count property to count and return the number of permission entries in the collection.

To retrieve each permission entry, the script uses the GPMSecurityInfo object's Item property, which returns a reference to a GPMPermission object. After the script assigns this reference to the Ace variable, the script uses the GPMPermission object's Trustee property to access the GPMTrustee object. By calling the GPMTrustee object's TrusteeName property, the script determines the name of the user or group assigned to the current permission, then assigns the name to the PrincipalName variable.

The code at callout C in Listing 2 uses a Select Case statement to determine the security right assigned to that user or group. A GPO can have five different security rights, as defined in the IGPMConstants interface. The Select Case statement contains these five rights.

The first line in the Select Case statement tells the VBScript runtime engine to compare the Ace.Permission value (i.e., the GPMPermission object's Permission property value) to each case. When the Permission property value matches one of the five security rights, the script assigns a user-friendly description of that permission to the Perm variable. Finally, the script uses WSH's WScript.Echo command to output the user's or group's name and permission to the console screen.

Listing 2 GetGPOPerms.vbs

BEGIN COMMENT
' Create the GPM and GPMConstants objects,
then connect to the domain.
END COMMENT
Set GPMC = CreateObject("GPMgmt.GPM")
Set Constants = GPMC.GetConstants()
‘ BEGIN CALLOUT A
Set GPMCDomain = GPMC.GetDomain("mycompany.net", "",
Constants.UseAnyDC)
‘ END CALLOUT A
‘ BEGIN CALLOUT B
BEGIN COMMENT
' Create an object for the GPO for which you want to list the
permissions.
END COMMENT
Set MyGPO = GPMCDomain.GetGPO
("{31B2F340-016D-11D2-945F-00C04FB984F9}")
BEGIN COMMENT
' Get the permissions.
END COMMENT
Set GPOSec = MyGPO.GetSecurityInfo()
‘ END CALLOUT B
For indx=1 to GPOSec.Count
BEGIN COMMENT
   ' Set the ACE to the Ace variable.
END COMMENT
   Set Ace = GPOSec.Item(indx)
BEGIN COMMENT
   ' Find out the username or group name for the ACE.
END COMMENT
   Set UsrorGrp= Ace.Trustee
   PrincipalName=UsrorGrp.TrusteeName
‘ BEGIN CALLOUT C
BEGIN COMMENT
   ' Find out which permission the user or group has.
END COMMENT
   Select Case Ace.Permission
      Case Constants.permGPOApply
         Perm="Read and Apply Group Policy"
      Case Constants.permGPOEdit
         Perm="Edit Group Policy"
      Case Constants.permGPOEditSecurityAndDelete
         Perm="Edit Group Policy, Modify Security and Delete
Group Policy"
      Case Constants.permGPORead
         Perm="Read Group Policy"
      Case Constants.permGPOCustom
         Perm="Custom Permission"
   End Select
‘ END CALLOUT C
   WScript.Echo "The User or Group: " & PrincipalName & _
      " has the following permission: " & Perm
Next