Private/Resolve-UserIdentity.ps1
|
function Resolve-UserIdentity { <# .SYNOPSIS Resolves any form of user identifier to a consistent user object. .DESCRIPTION Takes a UPN, SAMAccountName, email address, or display name and resolves it to a normalized object containing SAMAccountName, UPN, Mail, ObjectId, and DisplayName. Searches Active Directory in the following order: 1. SAMAccountName 2. UserPrincipalName 3. Mail attribute 4. DisplayName .PARAMETER Identity The user identifier to resolve. Accepts UPN, SAMAccountName, email, or display name. .OUTPUTS PSCustomObject with SAMAccountName, UPN, Mail, ObjectId, DisplayName properties. .EXAMPLE Resolve-UserIdentity -Identity "jsmith" .EXAMPLE Resolve-UserIdentity -Identity "john.smith@contoso.com" #> [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Identity ) $adProperties = @( 'SamAccountName' 'UserPrincipalName' 'Mail' 'ObjectGUID' 'DisplayName' 'Enabled' ) $adUser = $null # Strategy 1: Try as SAMAccountName (most common for quick lookups) Write-Verbose "Resolve-UserIdentity: Trying SAMAccountName match for '$Identity'" try { $adUser = Get-ADUser -Identity $Identity -Properties $adProperties -ErrorAction Stop } catch { Write-Verbose " Not found by SAMAccountName: $($_.Exception.Message)" } # Strategy 2: Try as UserPrincipalName if (-not $adUser) { Write-Verbose "Resolve-UserIdentity: Trying UPN match for '$Identity'" try { $adUser = Get-ADUser -Filter "UserPrincipalName -eq '$Identity'" -Properties $adProperties -ErrorAction Stop } catch { Write-Verbose " UPN filter failed: $($_.Exception.Message)" } } # Strategy 3: Try as mail attribute if (-not $adUser) { Write-Verbose "Resolve-UserIdentity: Trying mail attribute match for '$Identity'" try { $adUser = Get-ADUser -Filter "Mail -eq '$Identity'" -Properties $adProperties -ErrorAction Stop } catch { Write-Verbose " Mail filter failed: $($_.Exception.Message)" } } # Strategy 4: Try as DisplayName if (-not $adUser) { Write-Verbose "Resolve-UserIdentity: Trying DisplayName match for '$Identity'" try { $results = Get-ADUser -Filter "DisplayName -eq '$Identity'" -Properties $adProperties -ErrorAction Stop if ($results -is [array] -and $results.Count -gt 1) { Write-Warning "Multiple users found with DisplayName '$Identity'. Using the first match: $($results[0].SamAccountName)" $adUser = $results[0] } else { $adUser = $results } } catch { Write-Verbose " DisplayName filter failed: $($_.Exception.Message)" } } # Strategy 5: Wildcard fallback on DisplayName if (-not $adUser) { Write-Verbose "Resolve-UserIdentity: Trying wildcard DisplayName match for '$Identity'" try { $results = Get-ADUser -Filter "DisplayName -like '*$Identity*'" -Properties $adProperties -ErrorAction Stop if ($results -is [array] -and $results.Count -gt 1) { $names = ($results | ForEach-Object { "$($_.SamAccountName) ($($_.DisplayName))" }) -join ', ' throw "Multiple users matched wildcard search for '$Identity': $names. Please provide a more specific identifier." } elseif ($results) { Write-Verbose " Found via wildcard: $($results.SamAccountName)" $adUser = $results } } catch [Microsoft.ActiveDirectory.Management.ADFilterParsingException] { Write-Verbose " Wildcard filter failed: $($_.Exception.Message)" } } if (-not $adUser) { throw "Unable to resolve user identity '$Identity'. Tried SAMAccountName, UPN, mail, and DisplayName lookups. Verify the user exists in Active Directory." } [PSCustomObject]@{ SAMAccountName = $adUser.SamAccountName UPN = $adUser.UserPrincipalName Mail = $adUser.Mail ObjectId = $adUser.ObjectGUID.ToString() DisplayName = $adUser.DisplayName Enabled = $adUser.Enabled } } |