Working with Group Policy Objects Programmatically - Determining registry values to Enable/Disable/Set a specific policy
Greetings!
Over the past few months our team has seen a number of customer requesting information on how to programmatically/create/edit/read registry based GPO information. I took some time to combine a couple of samples into one that illustrates a number of these concepts.
The first question one must answer when working with a registry based GPO is the programmatic modification of this GPO setting supported by Microsoft. The general answer to that question is that if their exist public documentation on the MSDN or Tech Net site that provides information on the registry key paths and the possible values then, yes, programmatic modification is supported. In my sample, I used the excel spreadsheet available at the following MSDN link:
www.microsoft.com/en-us/download/details.aspx?id=25250
The spreadsheet contains a list of policies and their associated registry keys.
Remember, the GPO can have information stored in 3 different places:
- The Active Directory in the form of a GroupPolicyContainer object.
- The Sysvol of any DC, where GPO related INI file or POL file is created. The POL file is then written into the local machine registry in either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER. In addition to these two files, the GPO could store private data in a format known only to the GPO extension.
- The client system where a GPO extension could exist to process GPO private data.
The next step is to determine exactly what values need to be written to the keys in order to enable/disable/set the policy. While the key values are generally documented, there can be subtle differences in the values that the GUI recognizes and uses to determine if a GPO is enable/disable or set. I find that using the empirical method works best to solve this problem. Using the Group Policy Management Console GUI tool, I create a GPO with a specific display name like "MaxVs Test Policy". I set the policy that I want to set programmatically. Then I do a query in the Active Directory Users and computers tool to locate the GPO Object in the Active Directory. The GPO object contains a CN that is a GUID. This GUID can be used to locate the NTFS folder on the SYSVOL of a DC that the policy registry information was written to.
For example, if I created a GPO that sets the "Prevent access to the command prompt" under the "User Configuration" node:
User Configuration -> Policies -> Administrative Templates -> Security -> "Prevent access to the command prompt"
I enable it and set it. When I click the Apply button, a Registry.POL file will be created on the sysvol in a directory named after the common name of the GroupPolicyContainer object created in the AD. The path will look similar to the following:
C:\Windows\SYSVOL\sysvol\maxv08.nttest.microsoft.com\Policies\{529AB3E5-3818-42F5-9BDE-95629F33780C}\User
Where "maxv08.nttest.microsoft.com" will be the domain name of your domain and the GUID string will be the display name of the GPO you just created. At this point, you can view the POL file in notepad or using a binary file editor. If you use notepad, the contents would be similar to the following:
PReg [ S o f t w a r e \ P o l i c i e s \ M i c r o s o f t \ W i n d o w s \ S y s t e m ; D i s a b l e C M D ; ; ; ]
To see the actual values written in the key, you would need to use a binary editor that displays the binary representation for the values displayed above.
Copy this file to another location with a name that indicates the setting values.
Repeat this process for all the settings you wish to duplicate programmatically.
Once you know the registry values to write, we are ready to write the C++ code to set them.
Keep watching this blog, I will make another post that provides a function that illustrates how to set the "Prevent access to the command prompt" policy.