Private/Get-ManagerInfoFromEmailAcrossDomains.ps1
function Get-ManagerInfoFromEmailAcrossDomains { <# .SYNOPSIS Gets manager's info (email, department, samAccountName) using the user's email, searching across multiple AD domains. .PARAMETER UserEmail The email address of the user (mail attribute). .PARAMETER Domains List of DNS domain names to search. .OUTPUTS PSCustomObject with manager info or null if not found. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$UserEmail, [Parameter(Mandatory)] [string[]]$Domains ) # Escape special LDAP filter chars $safeEmail = $UserEmail -replace '([\\*()\0])', { '\{0:x2}' -f [byte][char]$args[0].Value } # LDAP user filter $userFilter = "(&(objectCategory=person)(objectClass=user)" + "(mail=$safeEmail)" + "(!(userAccountControl:1.2.840.113556.1.4.803:=2)))" foreach ($domain in $Domains) { # Convert to DC= format $dcParts = $domain -split '\.' | ForEach-Object { "DC=$_" } $domainNC = $dcParts -join ',' try { $searchRoot = [ADSI]"GC://$domainNC" $userSearcher = New-Object DirectoryServices.DirectorySearcher $userSearcher.SearchRoot = $searchRoot $userSearcher.SearchScope = "Subtree" $userSearcher.PageSize = 100 $userSearcher.Filter = $userFilter $userSearcher.PropertiesToLoad.Add("manager") | Out-Null $userResult = $userSearcher.FindOne() if ($userResult) { $managerDN = $userResult.Properties["manager"][0] if (-not $managerDN) { Write-Verbose "User found in $domain, but has no manager." return $null } # Bind to manager and get required properties $manager = [ADSI]("LDAP://$managerDN") return [pscustomobject]@{ UserName = $UserEmail ManagerDepartment = $manager.Properties["department"][0] ManagerEmail = $manager.Properties["mail"][0] ManagerSamAccount = $manager.Properties["samAccountName"][0] ManagerDN = $managerDN SourceDomain = $domain } } } catch { Write-Warning "Error querying domain $domain : $_" } } Write-Verbose "User not found in any supplied domain." return $null } |