Group Policy Object Autopsy

object359

It has been a phenomenal amount of time since my blog post about “Spelunking Group Policy,” and although I have thought of several other topics to write about in the intervening months, I thought it fitting to resume posting here with another article relating to both Group Policy and my good friend, Windows PowerShell.

Two of the most exciting cmdlets in the Windows PowerShell 2.0 GroupPolicy module (included in the Remote Server Administration Tools (RSAT) or also available on Active Directory Domain Services Domain Controllers) are Set-GPRegistryValue and Set-GPPrefRegistryValue. I refer to them as exciting because after the initial joy of using New-GPO to create one or thousands of new Group Policy Objects, the thrill wears off and the temptation to do one of things might set it.

For some of you, the temptation to resort to comfort of the Graphical User Interface (GUI) Group Policy Management Console (GPMC), pointing and clicking (or touching and tapping if you’re connected in via an iPad, Android Tablet, or one of those recently end-of-lifed HP TouchPads) on the GPO and choosing “Edit” from the menu to invoke the also very graphically-oriented Group Policy Management Editor (GPME) can lead you to stray from the realm of automation and scripting and into the imperative touch-and-tap (do you really still point-and-click?) interface of the GUI GPME.

Others of you might fall to another temptation. Yes, creating a Registry.POL file directly from scratch to represent the settings you would like to have configured in your precious GPO. That technique is not for the feint of heart.

The middle way, a potentially more Zen approach, let’s you use the GUI and PowerShell to get into the anatomy of a GPO with the precious settings you need and transplant some of these good and easy to understand settings into another body, namely another GPO. The best part of it is that you can use PowerShell to inject these settings into other GPOs either by cloning from an example, or by learning the representation of the settings you need and crafting brand new instances of those settings and grafting them into a new GPO.

Let’s start with a simple but useful setting which allows script execution in Windows PowerShell. If you know how to find this setting in the GPME, then you can learn how to use PowerShell on a management station to automate configuration of this setting. In the GPME, navigate to Computer Configuration -> Policies -> Administrative Templates -> Windows Components -> Windows PowerShell. Within that category (key), the yellow folder called “Windows PowerShell,” there should be a setting (value) on the right-hand pane of the GPME called “Turn on Script Execution.” If you edit that policy setting graphically, you will see that it can either be Disabled or Enabled, or the tristate default Not Configured. Disabling this setting is like locally assigning “Set-ExecutionPolicy Restricted” which is no fun. Secure perhaps, but not fun when you need to run scripts. Enabling the “Turn on Script Execution” setting provides three possible values for the Execution Policy option: Allow only signed scripts, Allow local scripts and remote signed scripts, and Allow all scripts. These correlate to execution policy values in the shell (e.g. with Set-ExecutionPolicy) of AllSigned, RemoteSigned, and Unrestricted, respectively. As an example, let’s assume that we have configured this as Enabled and “Allow local scripts and remote signed scripts” and applied this change to the GPO.

Once you have configured such a Group Policy setting in the GPM Editor in this way, you can go back into Windows PowerShell and investigate what setting was actually configured. You don’t even have to look up the setting in the administrative templates .ADMX and .ADML files (or classic .ADM either). And better still, you don’t have to manually dig through the Registry.POL file to determine what settings have been configured (although that is always educational). The easier way is to use the Get-GPRegistryValue cmdlet. Assuming that you have done an “Import-Module GroupPolicy” and are ready to use this cmdlet, you could refer back to my blog post about “Spelunking Group Policy” to find the values. Let’s assume that you have done such spelunking and navigated down to the proper key and found that the key “HKLMSoftwarePoliciesMicrosoftWindowsPowerShell” now has some values.

Get-GPRegistryValue "Enable PowerShell Scripting" -Key "HKLMSoftwarePoliciesMicrosoftWindowsPowerShell"

The above incantation in PowerShell should reveal the following information:

KeyPath : SoftwarePoliciesMicrosoftWindowsPowerShell
FullKeyPath : HKEY_LOCAL_MACHINESoftwarePoliciesMicrosoftWindowsPowerShell
Hive : LocalMachine
PolicyState : Set
Value : 1
Type : DWord
ValueName : EnableScripts
HasValue : True
KeyPath : SoftwarePoliciesMicrosoftWindowsPowerShell
FullKeyPath : HKEY_LOCAL_MACHINESoftwarePoliciesMicrosoftWindowsPowerShell
Hive : LocalMachine
PolicyState : Set
Value : RemoteSigned
Type : String
ValueName : ExecutionPolicy
HasValue : True

This quick technique enables you to find values within existing GPOs which could then either be cloned or assigned from scratch into a new GPO. That is the topic of the next article.