Enumerate Through OUs in AD

Posted Sunday, February 13, 2011 in Old JamesCMS Posts

Ok, here's a powershell script that performs a few operations:

Enumerates through all OU's from root to farthest child (hmm, sounds strange…) At each OU two AD queries are ran to get the number of admin type accounts (just change the filter to get something else) OU name extraction using regex (I had already modified this again to extract and format the OU as Parent\Child) Try http://gskinner.com/RegExr/ its indispensable for testing regex Does a bit of formatting, instead use `t for tabs to replace the pipes I put in. You can pipe the output to a csv file to get a bit of formatting. It's not pretty but its readable.

 function Process-OU ([adsi]$entry){            
     $entry | select distinguishedName | Out-Null            
     $entry.psbase.children |            
         Where-Object {$_.objectClass -contains "organizationalUnit" -and             
         $_.distinguishedName.ToString().StartsWith("OU=Users") -eq 0} |            
         ForEach {            
             #regex to get OU name            
             $pattern = "OU=([a-zA-Z0-9 ]*)"            
             $_.distinguishedName.ToString() -match $pattern | Out-Null            
             $result = $matches[1]            
             $result2 = ""            
             $strFilter = "($(objectCategory=user)(samAccountName=*.mngr))"            
             $objDomain = New-Object System.DirectoryServices.DirectoryEntry            
             $objSearcher = New-Object System.DirectoryServices.DirectorySearcher            
             $objSeearcher.SearchRoot = $_.Path            
             $objSeearcher.PageSize = 1000            
             $objSeearcher.Filter = $strFilter            
             $objSeearcher.SearchScope = "Subtree"            
             $colPropList = "name", "title"            
             foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i) | Out-Null}            
             $colResults = $objSearcher.Findall()            
             $result += "|$($colResults.count)"            
             Foreach ($objResult in $colResults)            
             {$objItem = $objResult.Properties            
                 $result2 += "`n|||" + $objItem.name            
             $strFilter = "($(objectCategory=user)(samAccountName=*.admin))"            
             $objSearcher.Filter = $strFilter            
             $colResults = $objSearcher.Findall()            
             $result += "|$($colResults.count)"            
             $result += $result2            
             Foreach ($objResult in $colResults)            
             {$objItem = $objResult.Properties            
                 $result += "`n||||" + $objItem.name            
             echo $result            
             Process-OU $_            

Edit: Looking at this now it would have been much better to generate a new object for each OU and return an array of such objects so you could manipulate the data later on. Oh well…