functions/Resolve-SPGraphUser.ps1

function Resolve-SPGraphUser {
    <#
    .SYNOPSIS
        Resolves information about the specified user identifiers.
     
    .DESCRIPTION
        Resolves information about the specified user identifiers.
        This specifically will return all groups the user is a member of - directly or nested.
     
    .PARAMETER Identity
        UPN or ID of the users to resolve.
 
    .PARAMETER LogLevel
        How detailed a log should be written.
     
    .EXAMPLE
        PS C:\> Resolve-SPGraphUser -Identity fred@contoso.onmicrosoft.com
 
        Resolves the user fred@contoso.onmicrosoft.com
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('id', 'upn', 'UserPrincipalName')]
        [string[]]
        $Identity,

        [LogLevel]
        $LogLevel = 'Medium'
    )

    process {
        foreach ($name in $Identity) {
            if ($LogLevel -gt 0) { Write-PSFMessage -Message 'Resolving user {0}' -StringValues $name -Target $name }
            try { $userHash = Invoke-EntraRequest -Path "users/$($name)?`$select=userPrincipalName,displayName,id" -ErrorAction Stop }
            catch {
                Write-PSFMessage -Level Warning -Message 'Unable to retrieve user {0}' -StringValues $name -ErrorRecord $_ -Target $name -PSCmdlet $PSCmdlet
                continue
            }
            if (-not $userHash.id) {
                Write-PSFMessage -Level Warning -Message 'Unexpected result for {0}. Response in Target.' -StringValues $name -Tag unexpected -Target $userHash
                continue
            }
            $userHash = $userHash | ConvertTo-PSFHashtable

            $userHash.Groups = @{ }
            $userHash.Identities = @()
            Resolve-SPGraphUserGroupMembership -Identity $userHash.id -Data $userHash.Groups -LogLevel $LogLevel
            $userObject = [PSCustomObject]$userHash
            $userObject.Identities = @($userObject.userPrincipalName) +
                                     @($userObject.Groups.Values.Where{$_.UserPrincipalName}.UserPrincipalName) +
                                     @($userObject.Groups.Values.Where{$_.Mail}.Mail) +
                                     @($userObject.Groups.Values.Id)
            if ($LogLevel -gt 0) { Write-PSFMessage -Message 'User is member in {0} groups (directly or indirectly)' -StringValues $name -Target $name }
            $userObject
        }
    }
}