One-Liner: Use PowerShell to Get GPOs Containing User Settings
Last week we used Get-ADObject to find GPOs based on their flags attribute. We targeted GPOs that were configured with user settings enabled and computer settings disabled.
This week we'll find GPOs containing user settings. I'll show you two ways, the second of which is preferred...
Way, the first - Get-GPOReport
Get-GPO -All | ForEach-Object {
([XML](Get-GPOReport -Guid $_.ID -ReportType Xml) | Where-Object {$_.GPO.User.ExtensionData -ne $null}).GPO.Name
}
What's going on?
- Get all the GPOs in the current domain with Get-GPO
- Pipe each found GPO into a ForEach-Object loop
- Within the ForEach-Object loop execute Get-GPOReport for the current GPO in the pipeline and make the -ReportType XML
- Cast the resultant string object to [XML] and pipe it into Where-Object
- Use Where-Object to filter on GPOs with the ExtensionData node present under the User node
- Display the name of the filtered GPO from the XML object, using dot notation
Way, the second - Get-ADObject
Think about this. The first way will find policies that have User extension data populated, but also have the User settings disabled. What to do? Well, you could refer to last week's post to find GPOs with both 'User Enabled / Computer Enabled' and 'User Enabled / Computer Disabled' and then pipe these objects into the above loop, i.e. replace Get-GPO -All with these filtered objects. Fair enough.
But, what if the first way also finds policies that used to contain user settings but have since had them removed. Hmmm - that would be trickier to filter out... not insurmountable with the right XML navigation, but definitely trickier...
Let's switch from the GroupPolicy PowerShell module to the ActiveDirectory PowerShell module and take a look at this rather nifty LDAP query...
Get-ADObject -LDAPFilter “(&(objectclass=groupPolicyContainer)(!(flags:1.2.840.113556.1.4.803:=1))(gPCUserExtensionNames=*)(!(gPCUserExtensionNames=' ')))” -SearchBase "cn=Policies,cn=System,dc=halo,dc=net" -Properties DisplayName,gPCUserExtensionNames | Select DisplayName,DistinguishedName,gPCUserExtensionNames
What's going on?
Let's take a look at the components of the LDAP query. The key is the gPCUserExtensionNames attribute which may be present on the Group Policy Containers (GPCs) in Active Directory:
- (!(flags:1.2.840.113556.1.4.803:=1)) - this excludes GPOs that have the disable user options flags set
- (gPCUserExtensionNames=*) - this includes GPOs that have the gPCUserExtensionNames set
- (!(gPCUserExtensionNames=' ')) - this excludes GPOs that have gPCUserExtensionNames set to a single space, i.e. those that used to have user settings but no longer do
To recap - the LDAP query filters out GPOs
- that have user settings disabled
- that do not user extension data present
- that used to contain user settings, but no longer do
I mentioned this is my preferred way. Here's why:
- LDAP is MUCH faster than running Get-GPO and then Get-GPOReport for all policies
- I have access to useful properties as I'm dealing with an object representing the GPC rather than an XML report
- There may be issues with the results of Get-GPOReport depending on a number of factors, e.g. third party extensions
Comments
- Anonymous
August 26, 2016
The comment has been removed - Anonymous
October 05, 2016
is it possible to generate a similar report (csv) with the actual settings and values? I am having a hard time parsing the xml files. thank you in advance Ian - Anonymous
October 05, 2016
... I meant the settings inside the GPOs