Using WMI to Verify Group Policy

Scenario:

My name is Benjamin Morgan and I’m a Platforms PFE. Recently I was working with a customer on a Windows 10 upgrade project and they posed an interesting requirement. They needed to be able to verify that their required group policies were being applied and they needed to be able to run a report on any computer to verify compliance. I knew that System Center Configuration Manager could be utilized to run the compliancy report but finding the proper settings to report on was not as simple.

At first, I was thinking that if Group Policy wasn’t applying then you would see a lot of issues and there should be a change management process in place to ensure all policies are known. But, the more I thought of their requirement the more sense it made, and I was curious how best to do it.

It is important to note that, although I talk about System Center Configuration Manager in this article, the method discussed is applicable outside of CM as well!

Approach:

I know that Configuration Manager can be utilized to create compliance items and that the majority of the customer’s policies are registry items, so those are easy to look for but what about user rights assignment policies and the non-registry policies? Well WMI to the rescue.

There is a WMI namespace “root\rsop\computer” and within that namespace all the security settings for policies can be found, you just need to query under the class “RSOP_SecuritySettings”. As the setting names in WMI do not necessarily match the setting names in Group Policy, I found that it was easiest to create a brand-new policy and query specifically against that policy setting to create the compliance item. The query that I used to find the information that I was looking for was:

Get-CimInstance -Namespace root\rsop\computer -Query "select * from rsop_securitysettings" where {$_.gpoid -like '*{Insert GPO ID here}*'}  

 

After finding the necessary settings I then created a PowerShell script to look for the setting that I wanted and then I could report compliance on the setting.

For example, I want the “Account Lockout Policy” settings to look like this:

But I am concerned that there might be overriding policies hiding elsewhere and that computer X is not following my baseline. So, I make a new policy and set this specific setting against a test machine that I can utilize. After doing a gpupdate / force, I make note of the policy GUID and it happens to be {9EF0B492-803D-4C1C-9FC3-745C30928DE3}. I found this on the details page of the new test policy and it is marked as:

I then open an administrative PowerShell to run my command in to see exactly what the settings look like in WMI.

As shown earlier the command that I will run is:

Get-CimInstance -Namespace root\rsop\computer -Query "select * from rsop_securitysettings" where {$_.gpoid -like '*{9EF0B492-803D-4C1C-9FC3-745C30928DE3}*'}

 

The result that is returned looks like:

Armed with this information I could make a PowerShell script to verify the compliance settings. Since I wanted to know exactly what isn’t compliant I opted to make three different scripts, one for each setting but a single script would have worked as well.

Script 1

This script will be for the “Account lockout duration” setting.


$LockoutDuration Get-CimInstance -Namespace root\rsop\computer -Query "select * from rsop_securitysettings" |  where {$_.KeyName -eq 'LockoutDuration'-and $_.precedence -eq '1'
if (($LockoutDuration).setting -eq '4294967295'){ 
write 'Compliant' } 
else{ 
write 'Not-Compliant' } 

 

Script 2

This script will be for the “Account lockout threshold”


$LockoutThreshold Get-CimInstance -Namespace root\rsop\computer -Query "select * from rsop_securitysettings" |  where {$_.KeyName -eq 'LockoutBadCount' -and $_.precedence -eq '1'} 
if (($LockoutThreshold).setting -eq '5'){ 
write 'Compliant' } 
else{  write 'Not-Compliant' } 

 

Script 3

This script will be for the “Reset account lockout counter after”


$LockoutCount Get-CimInstance -Namespace root\rsop\computer -Query "select * from rsop_securitysettings" |  where {$_.KeyName -eq 'ResetLockoutCount' -and $_.precedence -eq '1'}
if (($LockoutCount).setting -eq '30'){ 
write 
'Compliant' } 
else{ 
write 'Not-Compliant' } 

 

The reason why I included the statement “$_.precedence -eq ‘1’” was because when the query is run it will call back all settings and the only settings that I care about are what are actually applied. I wrote back ‘Compliant’ and ‘Not-Compliant’ because I knew that Configuration Manager’s configuration items can look for return strings to determine success.

Hopefully you’ll find this information helpful in future endeavors. Thanks for reading!