Wednesday, February 2, 2011

Enumerate Objects in an Organizational Unit

In the example code below, I show how to return the objects within an organizational unit without venturing into subordinate organizational units. A future post will cover how to enumerate objects in nested organizational units which is similar to walking a directory tree as I did in "Searching for Files in Nested Directories". To make the exercise a little interesting, I am pointing to the Users container in the root of a forest of the security context the script is executed, building a report of user objects and saving selected attributes in a comma separated value text file. I use techniques from my "Get Object Active Directory Domain from distinguishedName" and "Return a Local Domain Controller in the Current Site for a Specific Domain" blog entries and rolled them into functions. Those two functions are used by a new function called Get-ActiveDirectoryObject which assists in obtaining the organizational unit object and the user object's manager attribute's user object. One note, pay attention to string replace I do on the distinguished name variable in the Get-ActiveDirectoryObject function. A common gotcha I have encountered are forward slashes (i.e., "/") in the distinguished name. You have to escape them in order to obtain the object or you get see red error messages.
Function Get-LocalDomainController($objectDomain) {
 return ([System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite()).Servers | Where-Object { $_.Domain.Name -eq $objectDomain } | ForEach-Object { $_.Name } | Select-Object -first 1
}

Function Get-ObjectADDomain($distinguishedName) {
 return ((($distinguishedName -replace "(.*?)DC=(.*)",'$2') -replace "DC=","") -replace ",",".")
}

Function Get-ActiveDirectoryObject($distinguishedName) {
 return [ADSI]("LDAP://" + (Get-LocalDomainController (Get-ObjectADDomain $distinguishedName)) + "/" + ($distinguishedName -replace "/","\/"))
}

#--------------------------------------------------------------------------------------------------#
# Modify the startingOU variable below to a significant organizational unit that contains user objects
Set-Variable -name forestRootDn -option Constant -value ([ADSI]("LDAP://" + (([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).name) + "/rootDSE")).defaultNamingContext
Set-Variable -name startingOu -option Constant -value "CN=Users,$forestRootDn"
#--------------------------------------------------------------------------------------------------#

$ouObject = Get-ActiveDirectoryObject $startingOu
$users = @()
foreach($childObject in $ouObject.psBase.Children) {
 if($childObject.objectClass -eq "user") {
  if($childObject.manager) {
   $managerObject = Get-ActiveDirectoryObject ($childObject.manager).ToString()
   if($managerObject.displayName) {
    $manager = ($managerObject.displayName).ToString()
   } else {
    $manager = (($managerObject.sn).ToString() + ", " + ($managerObject.givenName).ToString())
   }
  } else {
   $manager = "N/A"
  }
  $user = New-Object -typeName PSObject
  Add-Member -inputObject $user -type NoteProperty -name "domain" -value (Get-ObjectADDomain ($childObject.distinguishedName).ToString()).Split(".")[0]
  Add-Member -inputObject $user -type NoteProperty -name "sAMAccountName" -value (($childObject.sAMAccountName).ToString()).ToLower()
  Add-Member -inputObject $user -type NoteProperty -name "givenName" -value ($childObject.givenName).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "sn" -value ($childObject.sn).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "displayName" -value ($childObject.displayName).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "mail" -value (($childObject.mail).ToString()).ToLower()
  Add-Member -inputObject $user -type NoteProperty -name "title" -value ($childObject.title).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "department" -value ($childObject.department).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "manager" -value $manager
  Add-Member -inputObject $user -type NoteProperty -name "physicalDeliveryOfficeName" -value ($childObject.physicalDeliveryOfficeName).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "streetAddress" -value (($childObject.streetAddress).ToString() -Replace "`r`n",", ")
  Add-Member -inputObject $user -type NoteProperty -name "l" -value ($childObject.l).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "st" -value ($childObject.st).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "postalCode" -value ($childObject.postalCode).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "c" -value ($childObject.c).ToString()
  Add-Member -inputObject $user -type NoteProperty -name "telephoneNumber" -value ($childObject.telephoneNumber).ToString()
  $users += $user
 }
}
$users | Export-Csv -path (($ouObject.name).ToString() + ".csv") -noTypeInformation

No comments:

Post a Comment