Listing Disabled GPOs in a Forest

This blog post is written by Judith, our technical writer, and based on an old blog post by Jeffrey Snover. (https://blogs.msdn.com/b/powershell/archive/2007/01/11/sorting-out-groupby.aspx) Jeffrey wrote a piece that showed how to sort system services with the Format-Table (ft) cmdlet and the –GroupBy parameter.

This is one of those tidbits that when I come across them I wonder how I can use this for making it easier to create Group Policy reports. So, here’s what I’m thinking:

If you administer Group Policy in a somewhat large enterprise then you’ve probably got hundreds, if not thousands, of GPOs to deal with.

If you’re like me, I used to grab a listing of GPOs, throw the listing into Excel and start playing games with the data. Well, what if you could pretty quickly grab GPO data on the fly and play some games with it?

More importantly, what if you could grab GPO data on the fly, not just for a single domain, but for your whole forest? But wait, you say. We already did that. Actually, I already wrote a blog post on how to list all the GPOs for a forest. And if you haven’t read that, you can find it here: https://blogs.technet.com/b/grouppolicy/archive/2011/06/10/listing-all-gpos-in-the-current-forest.aspx.

But what if you could look for all the GPOs in your entire forest and list them based on the GPO status? In other words, list all GPOs in a forest with the disabled or partially disabled GPOs grouped separately. And you can do this in a single line of Windows PowerShell. Would you find that interesting? If you agree that this would be helpful then read on.

Jeffrey in his blog post explained that the Format-Table cmdlet has a parameter –GroupBy that tells Format-Table to generate a series of tables instead of one big table. These tables will be based on the –GroupBy parameter.

Big note here. Before we get into the guts of the blog post, you need to remember to import both the Group Policy and Active Directory modules before running these cmdlets. In other words, GPMC is installed on server or client and Active Directory role is installed on server or AD tools are installed on client. Then from the Windows PowerShell command prompt, I need to run these two commands at the start of my session:

Import-Module ActiveDirectory

Import-Module GroupPolicy

I still have my little test domain called, corp.Contoso.com, with a child domain of HQ.corp.Contoso.com. And I can very easily use the Get-GPO cmdlet with the –all parameter to see all the GPOs in the entire forest with the following command:

(get-ADForest).domains | foreach { get-GPO -all -Domain $_ }

This will display all the GPO information, but it will come as the GPOs are read from each domain.

Now, it becomes clear why I started this blog mentioning Jeffrey Snover’s blog post about sorting a table using the –GroupBy parameter. I want to see all the GPO information grouped by the status of each GPO. What happens if I add Format-Table (with alias of ft) using the –GroupBy parameter to the end of my previous command line?

(get-ADForest).domains | foreach { get-GPO -all -Domain $_ } | Format-Table -GroupBy GpoStatus

This will group the GPOs, but not quite as I expected. Instead of one table for AllSettingsEnabled, another for AllSettingsDisabled, etc., I seem to be getting clumps of GPOs based on status. You can see that in this partial display.

clip_image002

There’s a technical reason that Jeffrey goes into in his blog post. But the short answer is that the Format-Table cmdlet processes the input as it comes to the cmdlet. There’s no place to hold the input in order to group all of the results together at once. Presorting the information in this case will get us what we really want.

I want to make sure the GPO status is sorted first. Then it’s a toss-up of whether I want to see GPOs in alphabetical order based on the display name or an alphabetized list of GPOs first grouped by domain. For this example, I’m going to list the GPOs in alphabetical order within the GPO status groups. I’ll leave it up to you to play with changing the order of the sort to see what happens.

(get-ADForest).domains | foreach { get-GPO -all -Domain $_ } | sort GpoStatus, DisplayName | Format-Table -GroupBy GpoStatus

Now, we get what we wanted a series of tables that show GPOS based on status: AllSettingsDisabled, UserSettingsDisabled, ComputerSettingsDisabled, and AllSettingsEnabled. Much better.

clip_image004

My only problem with this is I can’t see all the data because my screen isn’t wide enough. The other way of displaying all the data for GPOs worked better in this case. So, how can I group by GpoStatus, and get all my data?

The answer is once again pretty simple. The –GroupBy parameter also works for Format-List.

Running the following command gives me the results I want:

(get-ADForest).domains | foreach { get-GPO -all -Domain $_ } | sort GpoStatus, DisplayName | Format-List -GroupBy GpoStatus

You can try grouping by other things than GpoStatus. For example, you can DomainName, Owner, or WmiFilter. Or try sorting by CreationTime or ModificationTime.