MS16-072 – Known Issue – Use PowerShell to Check GPOs


UPDATE - 30/06/2016

Official detect and fix script released. See here:

Powershell script to adjust permissions for Authenticated Users on Group Policy

 

Further information:

Deploying Group Policy Security Update MS16-072 \ KB3163622

 


 

Hello,

There is a known issue with the application of particular GPOs once MS16-072 is applied. Click the following link and browse to 'Known Issues' for more information:

 MS16-072: Security update for Group Policy: June 14, 2016

In response, I've put together the below PowerShell example to help identify GPOs, from the current domain, that might experience the issue once the update is applied. The output should be the basis for further investigation, i.e. it lists GPOs that may need the 'Authenticated Users' read permission or 'Domain Computers' read permission adding.

Capture154

In the above image, a red 'WARNING:' message indicates a GPO that may experience the known issue.

There are also three types of 'INFORMATION' message*:

1) yellow - the GPO does not have an 'Authenticated Users' permission, but does contain a 'Domain Computers' permission

2) yellow - the GPO has an 'Authenticated Users' permission that is not 'GpoApply' (Read / Apply) or 'GpoRead' (Read)

3) white - the GPO has the expected 'Authenticated Users' permission.

*NB - all three 'INFORMATION:' messages can be commented out in the script to reduce the output to screen, although the first two may require further investigation

You should also take a look here:

New Group Policy Patch MS16-072– “Breaks” GP Processing Behavior

Cheers,

Mr P. Chap.

 


#Load GPO module
Import-Module GroupPolicy
#Get all GPOs in current domain
$GPOs = Get-GPO -All
#Check we have GPOs
if ($GPOs) {
#Loop through GPOs
foreach ($GPO in $GPOs) {
#Nullify $AuthUser & $DomComp
$AuthUser = $null
$DomComp = $null
#See if we have an Auth Users perm
$AuthUser = Get-GPPermissions -Guid $GPO.Id -TargetName "Authenticated Users" -TargetType Group -ErrorAction SilentlyContinue
 #See if we have the 'Domain Computers perm
$DomComp = Get-GPPermissions -Guid $GPO.Id -TargetName "Domain Computers" -TargetType Group -ErrorAction SilentlyContinue
 #Alert if we don't have an 'Authenticated Users' permission
if (-not $AuthUser) {
#Now check for 'Domain Computers' permission
if (-not $DomComp) {
                Write-Host "WARNING: $($GPO.DisplayName) ($($GPO.Id)) does not have an 'Authenticated Users' permission or 'Domain Computers' permission - please investigate" -ForegroundColor Red
}   #end of if (-not $DomComp)
else {
#COMMENT OUT THE BELOW LINE TO REDUCE OUTPUT!
               Write-Host "INFORMATION: $($GPO.DisplayName) ($($GPO.Id)) does not have an 'Authenticated Users' permission but does have a 'Domain Computers' permission" -ForegroundColor Yellow
}   #end of else (-not $DomComp)
}   #end of if (-not $AuthUser)
elseif (($AuthUser.Permission -ne "GpoApply") -and ($AuthUser.Permission -ne "GpoRead")) {
#COMMENT OUT THE BELOW LINE TO REDUCE OUTPUT!
Write-Host "INFORMATION: $($GPO.DisplayName) ($($GPO.Id)) has an 'Authenticated Users' permission that isn't 'GpoApply' or 'GpoRead'" -ForegroundColor Yellow
}   #end of elseif (($AuthUser.Permission -ne "GpoApply") -or ($AuthUser.Permission -ne "GpoRead"))
else {
   #COMMENT OUT THE BELOW LINE TO REDUCE OUTPUT!
            Write-Output "INFORMATION: $($GPO.DisplayName) ($($GPO.Id)) has an 'Authenticated Users' permission"
        }   #end of else (-not $AuthUser)
    }   #end of foreach ($GPO in $GPOs)
}   #end of if ($GPOs)

 


Comments (39)

  1. Andrew Hurst says:

    Thanks for the script, the Get-GPPermission should be Get-GPPermissions?

    1. I have both in v5! 🙂

  2. gpoguy says:

    Cool script Ian. I like the check for custom permissions. I did an assess-fix script here: https://sdmsoftware.com/group-policy-blog/bugs/new-group-policy-patch-ms16-072-breaks-gp-processing-behavior/

    The one thing you may want to add, is a test to see if Domain Computers is in the ACL, since I believe that is sufficient to resolve this to? Also, because I think this only effects GPOs with per-user settings that use sec filtering, I test for that. Reduces the impact a bit.

    1. Thanks, Darren.

      Have added the ‘Domain Computers’ test and linked back to your post 🙂

  3. Get-GPPermissions is just an alias for Get-GPPermission 🙂

  4. xXReldasXx says:

    This is amazing. Thank you for posting this.

  5. Jason Porter says:

    If using Security Filtering, we are supposed to add Read permissions Domain Computers for the GPO. This script doesn’t check for that from what I see.

  6. Matt Schultz says:

    Thanks for providing this handy script. Much more elegant than the one-liner I wrote this morning!

  7. Anthony THomas says:

    How do I view the output?

    1. Hey, Anthony – new version will now provide output for non-conflict policies, too.

      1. curropar says:

        Too much output for me… So I’ve modified the Write-Output line for the non-conflict policies, and instead used Write-Verbose. Now I get that output just if I specify the -verbose parameter 😉

  8. Nickolas Noahubi says:

    Sorry I’m a bit of a noob when it comes to this. I do not have any output when I do this powershell. Is it only supposed to return results IF there is one that might conflict and if not, then it will just go back to my regular prompt?

    1. Correct, Nickolas.
      New version will now provide output for non-conflict policies, too.

      1. Nickolas Noahubi says:

        Hey Ian, Thank you very much for the response and thank you very much again for making this script. This has helped me and my teammates tremendously!!

  9. good stuff as always
    Thanks

  10. Matthew says:

    Converted to a function with object output so you can easily export to csv:

    Function Test-GPOAuthenticatedUsers{
    #Load GPO module
    Import-Module GroupPolicy

    #Get all GPOs in current domain
    $GPOs = Get-GPO -All

    #Check we have GPOs
    if ($GPOs) {
    #Loop through GPOs
    foreach ($GPO in $GPOs) {
    #Nullify $AuthUser
    $AuthUser = $null

    #See if we have an Auth Users perm
    $AuthUser = Get-GPPermissions -Guid $GPO.Id -TargetName “Authenticated Users” -TargetType Group -ErrorAction SilentlyContinue

    #Alert if we don’t have an ‘Authenticated Users’ permission
    if (-not $AuthUser) {
    $status = ‘Missing Authenticated Users Permission’
    } #end of if (-not $AuthUser)
    else {
    #Alert on a custom permission
    if ($AuthUser.Permission -eq “GpoCustom”) {
    $Status = ‘Custom Authenticated Users Permission’
    } #end of if (-not $AuthUser)
    else{
    $Status = $true
    }
    } #end of if (-not $AuthUser)
    [pscustomobject]@{‘DisplayName’=$GPO.DisplayName;’ID’=$GPO.ID;’Status’=$status}
    } #end of foreach ($GPO in $GPOs)
    } #end of if ($GPOs)
    }

    Test-GPOAuthenticatedUsers | Export-Csv -path c:\temp\gpoauthusersissues.csv -NoTypeInformation

  11. Most of our GPOs are linked to an OU where the computer objects reside. I think this is the case, but just to be clear…”domain computers” isn’t actually necessary if we have an “exception” GPO that overrides another, but only applies to a subset of machines (which are in turn added to security group), correct? It is just necessary that the computer object that needs the access, is able to read. Also, do you need to set the Read permission on the Security Filtering section, or can you just do it on the Delegation tab and only set Read (or…does it require Read+ApplyGPO)?

    1. Tom says:

      Have added Domain Computers were no authenticated users also missing on the delegation tab of each GPO for read. But your script still shows me all GPOs in red stating out both are missing.

  12. slemay says:

    Is there a way to allow this script to work for older SBS2008 servers? The Import-Module GroupPolicy is not valid in these installs.

  13. slemay says:

    Has anyone created a script that will produce this report but also allow you the option to repair? We have a bunch of clients we’re going to have to run this on – it would be nice to have a simple solution, once we “approve it” to have it repaired vs. having us automatically fix each one by hand.

  14. Matt Broadstock says:

    Thanks for the script!

    One thing, I found that the script was flagging GPOs where ‘Authenticated Users’ had GPORead instead of GPOApply permissions (which should be an OK situation, correct?).

    Changing this line seems to address those being flagged:
    #elseif ($AuthUser.Permission -ne “GpoApply”)
    elseif ($AuthUser.Permission -ne “GpoApply” -and $AuthUser.Permission -ne “GpoRead”)

    For completeness, the same types of checks could probably be added to the “else” section of the ” if (-not $DomComp) ” section but I doubt many environments would have something like that in place.

    Again, thanks for putting this together!

  15. tj says:

    Isn’t this over complicating the issue? If I understand correctly, the only change is the *retrieval* of the GPO? Authenticated Users includes computer objects, so if you check the permissions and it has Authenticated Users you are ok. If you do not have Authenticated Users, then you can check if you have Domain Computers. If you have Domain Computers you are ok. If you do not have either you may have an issue. You could add either one and be ok, I would choose to add Domain Computers as a least privilege approach.

    Here is a complete plagiarize and hack of the original script. It checks to see if Authenticated Users or Domain Computers permissions exist. If neither exists, it adds Domain Computers with GPORead permissions.

    $error.clear()
    clear-host

    #set to your location for the file containing GPOs that were updated with Domain Computers GPORead permissions
    $outfile = “c:\temp\GPO_check.txt”

    #Load GPO module
    Import-Module GroupPolicy

    #Get all GPOs in current domain
    $GPOs = Get-GPO -All

    $badGPO = 0

    #Check we have GPOs
    if ($GPOs) {

    #Loop through GPOs
    foreach ($GPO in $GPOs) {

    $checkgpo = $null

    $checkgpo = Get-GPPermissions -Guid $GPO.Id -TargetName “Authenticated Users” -TargetType Group -ErrorAction SilentlyContinue
    if ($checkgpo -eq $null) {$checkgpo = Get-GPPermissions -Guid $GPO.Id -TargetName “Domain Computers” -TargetType Group -ErrorAction SilentlyContinue}

    if ($checkgpo -eq $null) {
    Write-Host “WARNING: $($GPO.DisplayName) ($($GPO.Id)) does not have an ‘Authenticated Users’ or ‘Domain Computers’ permission – please investigate” -ForegroundColor Red
    $($GPO.DisplayName)|Out-File $outfile -Append
    $badGPO++
    Set-GPPermissions -Name $($GPO.DisplayName) -TargetName “Domain Computers” -TargetType Group -PermissionLevel GpoRead
    }

    } #end of foreach ($GPO in $GPOs)

    } #end of if ($GPOs)

    write-host “Count of updated GPOs $badGPO”

  16. Chris says:

    couple things on this.
    any way to specify a domain? i have 32 domains i manage. if you log in with an account from domain x on to domain y, the script will take your logon domain.
    can we specify a domain controller? since i have 100’s of dc’s, i’m waiting for replication. i tested this on a domain with 2 dc’s. made the change on one dc, and the script still didn’t show. i check the other dc, and replication didn’t go through yet. i’d like to be able to pinpoint 1 dc so that when i make updates, it will report back from that dc, not some other random dc.

    sorry I’m definitely learning powershell but by no means can write it. this is a bit above my powershell level.

  17. Walter says:

    When a script will be available via the KB homepage, it would be helpful if it can handle a multi-domain forest as well, e. g. by providing a domain parameter.
    Nevertheless, thanks for the script.

  18. Eric Lee says:

    It sounds like the security change in the MS16-072 patch will affect GPOs with User Settings only, is that right? If I’m understanding this correctly, we have some GPOs that contain only Computer Settings and won’t need to touch those… Can anyone confirm? Thanks

  19. Nice script Ian. I’ve taken your ideas and Darren’s script and rolled them into one big assessment and remediation script here: http://www.jhouseconsulting.com/2016/06/22/script-to-report-on-and-remediate-the-group-policy-security-change-in-ms16-072-1627

    Cheers,
    Jeremy

    1. norb says:

      Thanks for this!!

  20. May I suggest adding the following to your script for those of us who are not using English (‘Authenticated User’ is ‘Utilisateurs Authentifiés’ in French). So Why not use the SID of groups instead :

    # Get ‘Authenticated Users’ group name from SID
    $AuthUserSID = New-Object System.Security.Principal.SecurityIdentifier(“S-1-5-11”)
    $AuthUserName = ($AuthUserSID.Translate( [System.Security.Principal.NTAccount])).value

    # Get ‘Domain Computers’ group name from SID
    $DomCompSID = New-Object System.Security.Principal.SecurityIdentifier(“$(((get-addomain).DomainSID).value)-515”)
    $DomCompName = ($DomCompSID.Translate( [System.Security.Principal.NTAccount])).value

    After that you’ll have to fix ever -TargetName ‘Authenticated Users’ and -TargetName ‘Domain Computers’ to use the new variables :
    -TargetName $AuthUserName
    -TargetName $DomCompName

    Thanks for the script, saved me lot of time.

  21. heugy says:

    Nice script. thnx!

  22. Ethan Powell says:

    Maybe I did something wrong, but when I run this script I get errors:

    At D:\desktop\gpcheck.ps1:20 char:166
    + … omputers’ permission – please investigate” -ForegroundColor Red
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The string is missing the terminator: “.
    At D:\desktop\gpcheck.ps1:19 char:20
    + if (-not $DomComp) {
    + ~
    Missing closing ‘}’ in statement block or type definition.
    At D:\desktop\gpcheck.ps1:17 char:21
    + if (-not $AuthUser) {
    + ~
    Missing closing ‘}’ in statement block or type definition.
    At D:\desktop\gpcheck.ps1:8 char:25
    + foreach ($GPO in $GPOs) {
    + ~
    Missing closing ‘}’ in statement block or type definition.
    At D:\desktop\gpcheck.ps1:6 char:12
    + if ($GPOs) {
    + ~
    Missing closing ‘}’ in statement block or type definition.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

    1. Chad A says:

      Check the quotation marks….I had the same problem….had to convert the quotation marks in the script to standard ‘single’ and “double” quotes for it to work.

  23. Elio Panting says:

    I know this is fir the script but I do have a question about the solution, So am I understanding correctly that it is no longer possible to use Security Filtering by user groups? I have several policies that span multiple OUs and use Security filtering to pick out users by security group. Mainly these are for users that work in multiple departments.

  24. I just published a script to modify the defaultSecurityDescriptor attribute on the Group-Policy-Container schema class object: http://www.jhouseconsulting.com/2016/06/29/script-to-modify-the-defaultsecuritydescriptor-attribute-on-the-group-policy-container-schema-class-object-1668

    Hope people find that helpful.

    Cheers,
    Jeremy

  25. Suncode says:

    Thanks for sharing the script.

  26. Diego Azevedo says:

    I am having some issues to apply a GPO to a nested group structure using Security Filtering. I wonder whether that’s also caused by the same update. This is the scenario:

    AD Users: 1, 2, 3
    AD Groups: A, B, C
    Group C is a member of Group B
    Group B is a member of Group A

    GPO filtered to Group A

    User1: Member of group A – GPO applies successfully
    User2: Member of group B – GPO doesn’t apply (access is denied)
    User3: Member of group C – GPO doesn’t apply (access is denied)

    GPModeling tells me that all the 3 users

  27. Pascal Verdieu says:

    You can one-liner this and return an object instead of text, makes it easier to filter later on…

    Get-GPO -All | Select *,@{n=’AuthUser’;e={[bool](Get-GPPermissions -Guid $_.Id -TargetName “Authenticated Users” -TargetType Group -ErrorAction SilentlyContinue)}},@{n=’DomainComputers’;e={[bool](Get-GPPermissions -Guid $_.Id -TargetName “Domain Computers” -TargetType Group -ErrorAction SilentlyContinue)}}

Skip to main content