Public/Users/Find-GraphUser.ps1
# Module: Orbit # Function: Lookup # Author: David Eberhardt # Updated: 24-JAN-2021 # Status: Live # Add Search in ProxyAddresses - only display with an exact match function Find-GraphUser { <# .SYNOPSIS Returns User Objects from Azure AD based on a search string or UserPrincipalName .DESCRIPTION Simplifies lookups with Get-MgUser by using and combining -Search and -ObjectId Parameters. CmdLet can find uses by either query, if nothing is found with the Searchstring, another search is done via the ObjectId This simplifies the query without having to rely multiple queries with Get-MgUser .PARAMETER SearchString Required. A 3-255 digit string to be found on any Object. Performs multiple searches against this string and parts thereof. Starting with UserId, DisplayName, Surname and, if the SearchString contains an @-symbol, Mail & Mailnickname Returns unique objects only. .EXAMPLE Find-GraphUser [-SearchString] "John" Will search for the string "John" and return all Azure AD Objects found If nothing has been found, will try to search for by identity .EXAMPLE Find-GraphUser [-SearchString] "John@domain.com" First searches for a User with the UserId "John@domain.com" Then searches for DisplayNames or Surnames for string before a space or dot Finally searching Mail & Mailnickname for string before an "@" Return all Objects found .EXAMPLE Find-GraphUser -Identity John@domain.com,Mary@domain.com Will search for the string "John@domain.com" and return all Azure AD Objects found .INPUTS System.String .OUTPUTS PSCustomObject .NOTES None .COMPONENT UserManagement .FUNCTIONALITY Queries User Objects in Azure Ad with different mechanics .LINK https://github.com/DEberhardt/Orbit/tree/main/docs/Orbit.Users/Find-GraphUser.md .LINK https://github.com/DEberhardt/Orbit/tree/main/docs/about/about_UserManagement.md .LINK https://github.com/DEberhardt/Orbit/tree/main/docs/ #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0, ParameterSetName = 'SearchString', ValueFromPipeline, HelpMessage = 'Search string')] [ValidateLength(3, 255)] [string[]]$SearchString ) #param begin { Show-OrbitFunctionStatus -Level Live Write-Verbose -Message "[BEGIN ] $($MyInvocation.MyCommand)" # Asserting Graph Connection if ( -not (Test-GraphConnection) ) { throw 'Connection to Microsoft Graph not established. Please validate connection' } # Setting Preference Variables according to Upstream settings if (-not $PSBoundParameters['Verbose']) { $VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference') } $DebugPreference = if (-not $PSBoundParameters['Debug']) { $PSCmdlet.SessionState.PSVariable.GetValue('DebugPreference') } else { 'Continue' } $InformationPreference = if ( $PSBoundParameters['InformationAction']) { $PSCmdlet.SessionState.PSVariable.GetValue('InformationAction') } else { 'Continue' } } #begin process { Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand)" [System.Collections.Generic.List[object]]$Users = @() foreach ($String in $SearchString) { [System.Collections.Generic.List[object]]$Search = @() try { # UserId Write-Verbose -Message "Searching for Objects `"UserId:'$String'`"" $Result = Get-MgUser -UserId "$String" -WarningAction SilentlyContinue -ErrorAction STOP if ( $Result ) { $Users.Add($Result) } else { throw } } catch { $MgUserParams = @{ ConsistencyLevel = 'eventual' Count = 'userCount' WarningAction = 'SilentlyContinue' ErrorAction = 'Stop' } $Search.Add("DisplayName:$String") $Search.Add("Surname:$String") $UserPart = $String.split('@') | Select-Object -First 1 $Surname1 = $UserPart.split(' ') | Select-Object -Last 1 $Surname2 = $UserPart.split('.') | Select-Object -Last 1 $GivenName1 = $UserPart.split(' ') | Select-Object -First 1 $GivenName2 = $UserPart.split('.') | Select-Object -First 1 if ( -not $Search.contains("DisplayName:$UserPart")) { $Search.Add("DisplayName:$UserPart") } if ( -not $Search.contains("DisplayName:$Surname1")) { $Search.Add("DisplayName:$Surname1") } if ( -not $Search.contains("DisplayName:$Surname2")) { $Search.Add("DisplayName:$Surname2") } if ( -not $Search.contains("Surname:$Surname1")) { $Search.Add("Surname:$Surname1") } if ( -not $Search.contains("Surname:$Surname2")) { $Search.Add("Surname:$Surname2") } if ( -not $Search.contains("GivenName:$GivenName1")) { $Search.Add("GivenName:$GivenName1") } if ( -not $Search.contains("GivenName:$GivenName2")) { $Search.Add("GivenName:$GivenName2") } if ( -not $Search.contains("Mail:$UserPart")) { $Search.Add("Mail:$UserPart") } if ( -not $Search.contains("MailNickName:$UserPart")) { $Search.Add("MailNickName:$UserPart") } $Search | ForEach-Object { Write-Verbose -Message "Searching for Objects with `"$_`"" try { $Result = $null = Get-MgUser -Search "$_" @MgUserParams if ( $Result ) { Write-Verbose -Message "Found $($Result.Count) Object(s) with `"$_`"" $Users.Add($Result) } } catch { Write-Error -Message $_.Exception.Message } } } } # Output - Filtering objects if ( $Users ) { $Users | Sort-Object -Unique -Property ObjectId | Get-Unique | Sort-Object DisplayName } } #process end { Write-Verbose -Message "[END ] $($MyInvocation.MyCommand)" } #end } # Find-GraphUser |