PowerShell how to get around Active Directory referral errors

If you're getting referral errors from your PowerShell scripts trying to enumerate users the problem is most likely your LDAP search scope. An LDAP referral error occurs when you're searching in a domain that doesn't contain the user you're looking for. For example, if you're looking for user cn=foo,dc=HQ,dc=contoso,dc=com, but your search scope is set to dc=contoso,dc=com, the server may return a referral error. Some LDAP applications can handle referrals but for scripting you may want to try something less complex.

In the below example I contact the AD Global Catalog (GC) for the current domain and search for the AD "mail" attribute. The GC contains limited records of every AD object in the Forest. If I find the object I then get it's Distinguished Name (DN). The DN that returns can be from a domain other than the current domain (ex. cn=foo,dc=HQ,dc=contoso,dc=com). Then I cast the DN to an ADSI object so I can get/update it's properties. This gets you around the referral error!

# Contact AD Global Catolog to search for email address
 $dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
 $root = [ADSI]"GC://$($dom.Name)"
 $search = new-Object System.DirectoryServices.DirectorySearcher($root,"(mail=$stmail)")
 $result = $search.FindOne()

 if($result -ne $null)
 {
  $user = $result.GetDirectoryEntry()
  #write-host "User: " $user.distinguishedName " found" -ForeGroundColor Green;
 
  # cast each member as an ADSI object
  $user2 = $user.distinguishedName
  $adsPath = 'LDAP://' + $user2
  $account=[ADSI]$adspath
  $account.setinfo()
   
  #update all users
  $account.put($ManagerURI, $GrooveManager)
  $account.setinfo()
  write-host " Provisioned account: " $account.distinguishedName " " -ForeGroundColor Green; 
  $counter++

 }
 else
 {
  #$stmail
  write-host " Error: Member Email does not exist in Active Directory Global Catalog" -ForeGroundColor Red;
 }