internal/functions/ConvertTo-UserSitePermission.ps1

function ConvertTo-UserSitePermission {
    <#
    .SYNOPSIS
        Match Sharepoint permissions to users through recursive group membership.
     
    .DESCRIPTION
        Match Sharepoint permissions to users through recursive group membership.
        The result expresses the effective access a user has on a site (if any)
     
    .PARAMETER UserData
        The processed user information as returned by Resolve-SPGraphUser.
     
    .PARAMETER InputPermission
        The processed sharepoint site permissions as returned by Get-SPSitePermission
 
    .PARAMETER LogLevel
        How detailed a log should be written.
     
    .EXAMPLE
        PS C:\> $sites | Get-SPSitePermission | ConvertTo-UserSitePermission -UserData $userData
 
        Retrieves all permisions for sites stored in $sites, then matches the user info in $userData against it
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        $UserData,

        [Parameter(ValueFromPipeline = $true)]
        $InputPermission,

        [LogLevel]
        $LogLevel = 'Medium'
    )

    begin {
        $allIdentities = $UserData.Identities | Sort-Object -Unique

        $aadType = @{
            'AAD'     = 'Group'
            'AADRole' = 'Role'
        }
    }
    process {
        foreach ($permissionObject in $InputPermission) {
            # Skip entries that cannot be matched (Only AAD entities can be matched to an AAD user)
            if ($permissionObject.Type -notin 'AAD', 'AADRole') { continue }
            # Skip entries that have no match among our user data
            if ($permissionObject.ID -notin $allIdentities -and $permissionObject.Email -notin $allIdentities) { continue }

            foreach ($user in $UserData) {
                if (
                    $permissionObject.ID -notin $user.Identities -and
                    $permissionObject.Email -notin $user.Identities
                ) {
                    continue
                }

                $result = [PSCustomObject]@{
                    Site              = $permissionObject.Site
                    SiteIdentity      = $permissionObject.SiteIdentity
                    UserPrincipalName = $user.UserPrincipalName
                    Permission        = $permissionObject.Permission
                    Through           = $permissionObject.ID
                    Type              = $aadType[$permissionObject.Type]
                }
                if (-not $result.Through) {
                    $result.Through = $permissionObject.Email
                }
                if ($LogLevel -gt 0) { Write-PSFMessage -Message "User {0} has {1} permissions through {2} on {3}" -StringValues $result.UserPrincipalName, $result.Permission, $result.Through, $result.Site -Target $result }
                $result
            }
        }
    }
}