Author Posts

November 6, 2014 at 11:21 am

I have a requirement to find the total number of objects in Active Directory broken down by naming context. Currently, I have something like this:

$NamingContexts = [Get-AdRootDse].namingContexts
$AdObjects = [system.Collections.ArrayList]@[]
			foreach [$Nc in $NamingContexts] {
				$Objects = Get-AdObject -Filter * -SearchBase $Nc
				foreach [$Object in $Objects] {
					$Object | Add-Member -MemberType 'NoteProperty' -Name 'NamingContext' -Value $Nc -Force
					$AdObjects.Add[$Object] | Out-Null
				}
			}
			$AdObjects | Group-Object NamingContext

I'm not proud of it because it's horribly inefficient but I can't think of a better way. Anyone have any tips?

November 6, 2014 at 7:26 pm

If all you care about is the count, you don't need to store or group the actual objects. Something like this should be fine:

$NamingContexts = (Get-AdRootDse).namingContexts

$report = 
foreach ($Nc in $NamingContexts) {
    [pscustomobject] @{
        Context     = $Nc
        ObjectCount = (Get-AdObject -Filter * -Properties distinguishedName -SearchBase $Nc).Count
    }
}

$report | Format-Table -AutoSize

You may also find that this is one of the situations where it's preferable to use the ADSI classes instead of the AD module cmdlets, which tend to be quite a bit slower. Setting up an [adsisearcher] object and calling FindAll().Count would likely be a performance improvement.