Tuesday, October 20, 2015

Examining GPO Health

I was recently asked to evaluate an Active Directory environment to determine it's health, specifically relating to GPO's and how they were being used.

I discovered that the number and configuration of the OU's, GPO's, and contents, were a clear indication that the administration of GPO's was not well understood by the committee of people who were managing them, and that there were clearly problems being self-inflicted due to these issues.

The question, however, was how can we quickly assess whether the management of GPO's was in trouble, and also how can we quantify the issue?

The first thing to understand is that there are Recommended Best Practices from Microsoft for how to manage GPO's.  See https://technet.microsoft.com/en-us/library/cc785903(v=ws.10).aspx

But how to quantify these subjective suggestions?



First,  "Minimize the Use of the Block Policy Inheritance Feature".  


You can determine the number of OU's that have Blocked Policy Inheritance with the follow PowerShell command:

Get-ADOrganizationalUnit -Filter * | Get-GPInheritance | Where-Object {$_.GPOInheritanceBlocked}| measure

After having seen a "bad" install, I believe that the number should be less than 5% of the total number of OU's.  Or perhaps a raw number of 10-15 might be allowed.



Second, "Minimize the Use of the Enforce Feature".

How do you determine how many GPO's have Enforce Enabled?  How do I know where these are linked?
One quick way is to list all Links that are Enforced.
Use the following command:
Get-ADOrganizationalUnit -Filter * | Get-GPInheritance | Foreach {$_.GPOLinks } | Where {$_.Enforced} |  select DisplayName,Enabled,Enforced,Target

Another is to list the full set of GPO's linked to a single OU.  Example: for the OU=Servers there
Get-ADOrganizationalUnit "ou=servers,ou=corp,dc=mydomain,dc=com" | Get-GPInheritance |%{ $_.inheritedgpolinks }

This command will list the same information that is displayed in the GPMC GUI under the "Group Policy Inheritance" tab.  Note that the Order property is the order of the source GPO order on the applied OU, not the resulting order in the reported OU.  The property is listed in the precedence order of execution (backwards of course).

To report all OUs, and all links in all OU's, requires a bit more work.
$OUs = Get-ADOrganizationalUnit -Filter * | select DistinguishedName,LinkedGroupPolicyObjects,Name
$OUs += Get-ADDomain
$report = foreach ($ou in $OUs) {
   if ($ou.LinkedGroupPolicyObjects) {
   $inher = Get-GPInheritance -target $ou.DistinguishedName
   $count = 0
     foreach ($link in $inher.inheritedGpoLinks) {
       $count += 1
       "" | select-Object -property @{n="ou";E={$inher.Path}},
    @{N="Order";E={$count}},
       @{n="GPOname";e={$link.Displayname}},
    @{N="Enabled";E={$link.enabled}},
    @{N="Enforced";E={$link.enforced}},
    @{N="Target";E={$link.Target}}
     }
   }
  }

$report |export-csv .\GPO-Links-cwInheritance.csv  -NoTypeInformation


No comments: