Fix GPO permissions before applying MS16-072

While monitoring the PM.org mailing list yesterday, a problem with Group Policies was reported.

The problem was quickly identified on this Microsoft forum thread and the fix was documented a few hours later on this support page.

To quickly display GPO names that don’t have the Authenticated Users group, you can do:

Get-GPO -All | ForEach-Object { 
    # Test if Authenticated Users group have at least read permission on the GPO
    if ('S-1-5-11' -notin ($_ | Get-GPPermission -All).Trustee.Sid.Value) {
        $_
    }
} | Select DisplayName

To add back the Authenticated Users group with Read Permissions on the Group Policy Object (GPO), you can do:

Get-GPO -All | ForEach-Object { 
    if ('S-1-5-11' -notin ($_ | Get-GPPermission -All).Trustee.Sid.Value) {
        $_ | Set-GPPermission -PermissionLevel GpoRead -TargetName 'Authenticated Users' -TargetType Group -Verbose
    }
}

Now, every GPO has a permission set for the ‘Authenticated Users’ group and to check what permission is set for this group, you can do:

Get-GPO -All | ForEach-Object { 
    [PsCustomObject]@{
        DisplayName = $_.DisplayName
        Permission = ($_ | Get-GPPermission -TargetName 'Authenticated Users' -TargetType Group).Permission
    }
} | Out-GridView -Title 'Authenticated Users permissions'

Any (documented) ADSI changes in PowerShell 5.0?

I’ve been using for years the following ADSI code to query members of the local administrators group:

@(
([ADSI]"WinNT://./Administrators").psbase.Invoke('Members') |
% { 
 $_.GetType().InvokeMember('AdsPath','GetProperty',$null,$($_),$null) 
 }
) -match '^WinNT'

It works w/o any problem from PowerShell 2.0 to 4.0 and there are many code out there using this syntax.

I’ve noticed that there’s now a problem with the above syntax on PowerShell 5.0 running on Windows 7 or Windows 10.

The problem is precisely when the member is user. When we use the GetType() method, it reports:
Error while invoking GetType. Could not find member. Weird MissingMemberException 😦
When the member is a group, invoking GetType() still works.

How to fix this?
The best option is to have a piece of code that is compatible with any version of PowerShell and that doesn’t use the GetType() method invocation.

What about?

([ADSI]"WinNT://./Administrators").psbase.Invoke('Members') | % {
 ([ADSI]$_).InvokeGet('AdsPath')
}

Isn’t it more simple and less obscure? 😀

After using my Google-fu, some people reported this issue on stackoverflow.com about a year ago and the bug was also submitted to Microsoft on this page. What about also voting for it?