Breaking apart the GPO Modification Process and Using SCOM to Detect GPO Changes – Part 2

Disclaimer: Due to changes in the MSFT corporate blogging policy, I’m moving all of my content to the following location. Please reference all future content from that location. Thanks.

Part 1 is here.  In it, I covered monitoring for GPO changes or the creation of new GPOs.  As I learned when working through this, deleting and unlinking GPOs were a bit more difficult to track.

For my first test, I decided to remove an old GPO from my environment, and to my surprise, there was no alert. I checked my domain controller logs for 5141 events as well, and that confirmed what SCOM was telling me:  none were generated.  I went back and checked my various audit policies, and these were also set correctly.  After some digging, I made this little discovery.  5141 events are not turned on by default, you need to add the ‘delete’ SACL to the advanced auditing tab for your security group that can delete GPOs.  This can be done at the root domain level using Active Directory Users and Computers, but if you have not explicitly turned this on, it will not work.  It must also be done against the context of users who have the rights to modify a GPO.  In my case, I assigned it to the domain administrators group, but if there are users who can modify GPOs who are not members of this group, then no 5141 will be generated. Tracking this will involving knowing which groups can make changes to GPOs.


Once I got this turned on, I was able to generate 5141 events when I deleted a GPO, but I was still not seeing alerts in SCOM.  As it turns out, this too is a function of the way 5141 events are generated in Windows.  The ObjectClass value that we are capturing looks for groupPolicyContainer.  The value of this parameter, however, is ‘container’.  The Windows team switched it up on us unfortunately.  This happened for two of the three 5141 events that were generated.  The third one, however, uses the correct parameter.  Looking at the XML, I see why it wasn’t collected, as it looks like 5141s are being excluded.

I’m guessing this was an oversight, likely for testing purposes, but not cleaned out of the solution when presented.  Correcting that, however, brings us back to SCOM generating an alert for a PowerShell script failing to run due to differences in the parameterization of the event.  That’s not a big deal, but for the purposes of my security management pack, I’d rather generate an alert specifically targeting GPO deletion.  Since this is a singular event, I can use the same parameters for an alert generating rule, with a description that allows me to notify the users that a GPO was removed.  It doesn’t tell you the exact GPO, but it does tell you who did it, allowing for a security monitor to confirm.

Linking and unlinking GPOs does not behave as desired.  This event generates two 5136 events, so I’d hope the correlation script gets them, but it does not.  The reason is the same as what we saw when we deleted a GPO.  The ObjectClass changes for these 5136 events.  Linking and unlinking a GPO changes that parameter to domainDNS.  As such, the script as designed does not collect that information.  That is easy enough to correct.  In this case, correcting it should not add additional noise.  I simply added an <Or> expression to collect both domainDNS as well as grouppolicyContainer for that parameter.  Now that the script collects both, a GPO change alert is generated when a GPO is linked as well as unlinked.

There does appear to be a draw back here as well:  namely the GPO Name and GUID are blank.  Turning on debug for the script, I can see why.  The object DN is not the same in the 5136 event generated by linking/unlinking as it is when a 5136 that tracks GPO change.  There’s no GUID present, just the domain name. As such, the script is failing because it “cannot index into a null array.”


Even with the failure, the results we get are acceptable. I can see that a changed happened and who made it.  At this point, we can reach out to the individual and confirm the change, at which point we can close the alert.