Script to report on and remediate the Group Policy security change in MS16-072

On June 14th 2016 Microsoft released security update MS16-072 under KB3163622 that changes the behavior of Group Policy processing so that user group policies are now retrieved by using the machine’s security context instead of the user’s security context. This is a by-design behavior change from Microsoft to protect computers from a security vulnerability.

Update 23/06/2016: Microsoft finally released an official response to this patch via the Directory Services team: Deploying Group Policy Security Update MS16-072 \ KB3163622

This is a problem for people that implement security filtering on their Group Policy Objects (GPOs), as it removes the default Authenticated Users group not only from the “Apply group policy” permission, but also from the “Read” permission.

I found a great explanation of Authenticated Users in an old article here:

“But who exactly are Authenticated Users? The membership of this special identity is all security principals that have been authenticated by Active Directory. In other words, Authenticated Users includes all domain user accounts and computer accounts that have been authenticated by a domain controller on the network. So what this means is that by default the settings in a GPO apply to all user and computer accounts residing in the container linked to the GPO.”

So therefore Domain Computers will no longer have the rights to read a Group Policy Object (GPO). This has not necessarily been a problem…until now!

The KB article says that to fix it you can do one of two things:

Add the Authenticated Users group with Read permissions on the Group Policy Object (GPO).

If you are using security filtering, add the Domain Computers group with Read permissions on the Group Policy Object (GPO).

Update 23/06/2016: This is quite confusing as there is no clear instruction here. Which way do you go? After thinking about this further and taking in some of the commentary from various experts in this field, my default option on this is to add Domain Computers with Read permissions instead of Authenticated Users. This is viewed as the minimum required permissions and therefore most secure. You can indeed place computers into groups and apply those groups with Read permissions, but that’s starting to overcomplicate things, and means that you need an overall process to manage those groups.

I wanted a script that could first audit all GPOs that contained user settings and output that to a CSV file, which I could then attached to a change record. Don’t forget about Change Management! I then wanted the same script to perform the fix. By the time I got around to this, the awesome Darren Mar-Elia has produced a blog article and script: Group Policy Patch MS16-072– “Breaks” GP Processing Behavior

Darren also referenced an article from Ian Farr at Microsoft who also put together a script: MS16-072 – Known Issue – Use PowerShell to Check GPOs

Jeremy Moskowitz also put some information together in a blog article: Never a dull moment with Group Policy (or what to do about MS16-072)

The scripts and methods were not 100% what I was looking for. So I took the scripts and comments on their articles and enhanced Darren’s script to provide the output and process that I was after for all my customers.

Download the script and do the following:

Run the script with no parameters (in report only mode) and it will report on what GPOs with user settings are missing the Authenticated Users and/or Domain Computers Read permissions.

Open the CSV output file in Excel and filter the AuthUserRead for False and DomainComputersRead for False. This will leave you with a list of GPOs that need to be remediated.

Manually validate the output against some GPOs to ensure the script output is giving you valid information.

Create a Change Record and go through the approval process.

Decide if you want to give Domain Computers or Authenticated Users Read Permissions. If Domain Computers, then run with the script using the -Action parameter to fix the GPOs that require remediation. If Authenticated Users, then run with the script using the -Action -AuthUsers parameters to fix the GPOs that require remediation.

Run the script again with no parameters (in report only mode) to verify that there are no outstanding GPOs that require further remediation.

Complete the Change Record. Got to keep the Change Manager on side!

Update 02/07/2016: There have been several requests to make this script run against multiple domains so I have added a -Domains parameter. Here you can add 1 or more domains using the domains Fully Qualified Domain Name (FQDN) separated by a comma.

Update 30/07/2016: Fixed an issue when running against multiple domains where the script wasn’t using the “remote” domain name when assessing and setting the permissions. Thanks for the awesome feedback and testing by Trevor Bruss.

You don’t want to be concerned with setting these permissions each time a GPO is created, so you want to ensure that Domain Computers is set as a default Read permission. This is controlled by the defaultSecurityDescriptor attribute on the Group-Policy-Container schema class object:

Get my Script to modify the defaultSecurityDescriptor attribute on the Group-Policy-Container schema class object.

Darren also created a blog post to show how you can modify the default permissions that get stamped on a newly created GPO, to include Domain Computers with Read access by default.

Jeremy also included this in his article.

Update 24/06/2016: Thanks to Greg Onstot for finding a bug with the screen output at the end of the script. It would report that “No GPOs require modification” if the $ToBeFixed value was false. Greg provided an update to the script to address this that I have implemented into version 1.4. In my testing across a couple of different customer environments it was always giving me the correct output because the last GPO processed needed to be fixed.

Here is the AddGPOReadPerms.ps1 (1635 downloads) script:

Enjoy!