Resolving all Group Policy Preferences Variables

On the odd occasion that I need to use variables within Group Policy Preferences, I sometimes find myself wishing that there was a blog post that lists out exactly what the variables resolve to.

For example, does the %ProgramFilesDir% value include a trailing backslash? Or do I need to include one myself?

Sure, you can press F3 to bring up the list of variables, but it doesn’t provide example values:

Group Policy Preferences

I decided to use Group Policy Preferences itself to generate a list of the variables and their values. This was achieved through the INI file extension:

Screenshot of the Group Policy Editor, showing the rows of preference items in the INI Files section

I’ve exported these preference items to XML, so you can import them into a fresh GPO and test for yourself. Get the files here.

Screenshot of the Group Policy Management Console, showing where to drag the XML files in order to import them into the INI Files GPP area

I couldn’t get the User preferences extension to generate an INI file, and ran out of time to troubleshoot, but here’s all the variables pertaining to a Computer policy (I’ve obfuscated some values):

A table showing all of the GPP variables, and their values

Apologies for the image-based table. WordPress.com doesn’t make inserting tables particularly easy.

PowerShell: Get all unlinked GPOs

I decided to spend some of the quiet time now at the beginning of the new year to clean up Group Policy here at my new job. We had roughly the same number of GPOs as staff!

I’d already removed at least 10-20 GPOs manually, but I wanted a quick way to find all of the un-linked GPOs that were still just sitting around.

I found this great post by Mark Schill from back in 2013 that still does the job.

Mark’s solution, however, pulls out only the display name property. I needed to modify his solution a little, as I wanted to pipe the results to the Remove-GPO cmdlet. Here’s what I did:

Get-GPO -All | Where-Object { $_ | Get-GPOReport -ReportType XML | Select-String -NotMatch "<LinksTo>" }

The above one-liner gets all unlinked GPOs, and returns Microsoft.GroupPolicy.Gpo objects.

It goes without saying that you should be very careful when bulk-deleting anything. I first backed up all of my GPOs and dumped the list into text format to review it. I manually checked the settings on a few of the GPOs in question, and only then, deleted them.

Here’s how I generated the list to review:

$unlinkedGPOs = Get-GPO -All | Where-Object { $_ | Get-GPOReport -ReportType XML | Select-String -NotMatch "<LinksTo>" }
$unlinkedGPOs | Sort-Object -Property DisplayName | Select-Object DisplayName,CreationTime,ModificationTime | Format-Table

Apply GPO based on installed Server Feature (WMI Filtering)

Today I came across a server that had been placed in a sub-OU by a colleague simply for the purposes of applying a GPO to it. The GPO in question was configured to make some changes to the BranchCache feature.

If the policy needs to apply to a subset of all servers in an OU, it would be cleaner to apply a WMI filter to the GPO itself rather than limiting the scope of the GPO by explicit security filtering.

Here’s what I did to clean it up:

  1. Created a WMI filter in GPMC:
    SELECT * FROM Win32_ServerFeature WHERE Name like ‘branchcache%’
  2. Applied the filter to the GPO in question
  3. Applied the GPO to the OU where the server originally lived
  4. Moved the server back to the original OU

This same strategy could be used to apply a policy to all IIS servers, all file servers, etc. The possibilities are practically limitless.

You could even filter on something like Win32_Product to apply a specific GPO to Exchange servers, for example.

SELECT * FROM Win32_Product WHERE name = 'microsoft exchange server'

Don’t use Win32_Product. It’s not a good idea, and even Microsoft warn against using it.

WMI Filtering when working with Services in Group Policy Preferences

One good use of Group Policy Preferences is in controlling Windows Services. You can read how to do so here on Alan Burchill’s site, as it’s the same method that I use.

I sometimes go one step farther, and only apply that preference item if the service actually exists. “How do you do that?”, I hear you say. By using Item-Level Targeting and a WMI query.

One instance where I’ve used this previously is to control Adobe’s auto-update services. If the service doesn’t exist on a machine for one reason or another, the event logs will be full of errors like this:

The computer 'Disable Flash Player Update Service' preference item in the 'Policy Name Here {00000000-0000-0000-0000-00000000000}' Group Policy Object did not apply because it failed with error code '0x80070424 The specified service does not exist as an installed service.' This error was suppressed.

To test if the service is installed, first find out the Service Name, as opposed to the Display Name. That’s what we’ll use in the WMI query.

image

Then, apply the following WMI targeting query:

Query select * from win32_service where name = “AdobeARMservice”
Namespace Rootcimv2
Property Name
Variable Name  

The targeting editor should look like this afterwards:

image

Braindump: ADDS NTP Configuration via GPO

There’s a great article on the Microsoft AD team blog about configuring the authoritative time server automatically via group policy and WMI filters. This may save you from domain time sync issues if your PDC emulator role eventually ends up moving to a different server.

http://blogs.technet.com/b/askds/archive/2008/11/13/configuring-an-authoritative-time-server-with-group-policy-using-wmi-filtering.aspx

Their article covers how to set up the WMI filter, but doesn’t address the settings for NTP. Those are listed in detail under this support note.

These are the settings I’ve implemented in my GPO using Admin Templates->System->Windows Time Service:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeConfig]
"MaxNegPhaseCorrection"=dword:00000708
"MaxPosPhaseCorrection"=dword:00000708
"AnnounceFlags"=dword:00000005
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeParameters]
"Type"="NTP"
"ntpserver"="au.pool.ntp.org,0x1"
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeTimeProvidersNtpClient]
"Enabled"=dword:00000001
"SpecialPollInterval"=dword:00000384
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeTimeProvidersNtpServer]
"Enabled"=dword:00000001