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.


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:


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.


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

Use Group Policy Preferences to hide a physical drive

Just saw this note whilst browsing the help on Drive Maps in Group Policy Preferences:

You can use a Drive Map preference item to configure the visibility of a physical drive rather than a mapped drive. To do so, select the Update action, leave the Location field blank, select the drive letter of the physical drive, and then configure the Hide/Show this drive and Hide/Show all drives options.

So, to hide “A” drive (in this example), you’d configure the dialog box as follows:


I didn’t know this was possible. This may come in handy one day, if you want to hide something like an OEM partition that has had a drive letter assigned.