Public/Exchange/Mailbox/Get/Get-ExMailboxPermission.ps1

<#
    .SYNOPSIS
    Gets all permissions on an Exchange Online mailbox (Full Access, Send As, Send on Behalf)
 
    .DESCRIPTION
    This function retrieves and displays all permissions granted on a specific mailbox:
    - Full Access: Full access permissions to the mailbox
    - Send As: Permissions to send emails as the mailbox
    - Send on Behalf: Permissions to send emails on behalf of the mailbox
 
    .PARAMETER Identity
    The identity of the mailbox (email address, username, or display name)
 
    .PARAMETER ByDomain
    Filter mailboxes by domain name
 
    .PARAMETER UserPermission
    Find all permissions that a specific user has across all mailboxes (reverse lookup)
 
    .PARAMETER ExportToExcel
    Export the mailbox permissions to an Excel file
 
    .EXAMPLE
    Get-ExMailboxPermission -Identity "john.doe@contoso.com"
 
    Gets all permissions for the mailbox john.doe@contoso.com
 
    .EXAMPLE
    Get-ExMailboxPermission -Identity "john.doe@contoso.com" -ExportToExcel
 
    Gets all permissions for the mailbox and exports them to an Excel file
 
    .EXAMPLE
    Get-ExMailboxPermission -ByDomain "contoso.com"
 
    Gets all permissions for all mailboxes in the contoso.com domain
 
    .EXAMPLE
    Get-ExMailboxPermission -UserPermission "john.doe@contoso.com"
 
    Finds all mailbox permissions that john.doe@contoso.com has across all mailboxes
 
    .LINK
    https://ps365.clidsys.com/docs/commands/Get-ExMailboxPermission
 
    .NOTES
    Requires the ExchangeOnlineManagement module and an active connection to Exchange Online
    For Excel export functionality, requires the ImportExcel module
#>


function Get-ExMailboxPermission {
    param (
        [Parameter(Mandatory = $false, position=0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$Identity,

        [Parameter(Mandatory = $false)]
        [string]$ByDomain,

        [Parameter(Mandatory = $false)]
        [string]$UserPermission,

        [Parameter(Mandatory = $false)]
        [switch]$ExportToExcel,

        [Parameter(Mandatory = $false, HelpMessage = 'Optional output directory for the Excel export (defaults to the user profile).')]
        [string]$ExportPath
    )

    begin {
        $allPermissions = [System.Collections.Generic.List[PSCustomObject]]::new()
    }
    process {
        if ($UserPermission) {
            Write-Host "Finding all permissions for user: $UserPermission" -ForegroundColor Green

            # Get all mailboxes to check permissions against
            $mailboxes = Get-EXOMailbox -ResultSize Unlimited -Properties WhenCreated, WhenChanged, GrantSendOnBehalfTo
            Write-Host "Checking permissions across $($mailboxes.Count) mailbox(es)" -ForegroundColor Yellow

            # Set flag for reverse lookup mode
            $isUserPermissionLookup = $true
        }
        elseif ($ByDomain) {
            Write-Host "Retrieving permissions for all mailboxes in domain: $ByDomain" -ForegroundColor Green
            $mailboxes = Get-EXOMailbox -ResultSize Unlimited -Filter "EmailAddresses -like '*@$ByDomain'" -Properties WhenCreated, WhenChanged, GrantSendOnBehalfTo | Where-Object { $_.PrimarySmtpAddress -like "*@$ByDomain" }
            Write-Host "Found $($mailboxes.Count) mailbox(es) in domain $ByDomain" -ForegroundColor Yellow
            $isUserPermissionLookup = $false
        }
        elseif ($Identity) {
            Write-Host "Retrieving permissions for mailbox: $Identity" -ForegroundColor Green
            try {
                $mailboxes = @(Get-EXOMailbox -Identity $Identity -ErrorAction Stop -Properties WhenCreated, WhenChanged, GrantSendOnBehalfTo)
                Write-Host "Mailbox found: $($mailboxes[0].DisplayName) ($($mailboxes[0].PrimarySmtpAddress))" -ForegroundColor Yellow
            }
            catch {
                Write-Error "Error retrieving mailbox '$Identity': $($_.Exception.Message)"
                return $null
            }
            $isUserPermissionLookup = $false
        }
        else {
            Write-Host 'Retrieving permissions for all mailboxes' -ForegroundColor Green
            $mailboxes = Get-EXOMailbox -ResultSize Unlimited -Properties WhenCreated, WhenChanged, GrantSendOnBehalfTo
            Write-Host "Found $($mailboxes.Count) mailbox(es)" -ForegroundColor Yellow
            $isUserPermissionLookup = $false
        }
        $totalMailboxes = $mailboxes.Count
        $currentMailbox = 0
        foreach ($mailbox in $mailboxes) {
            $currentMailbox++
            Write-Host "Processing mailbox $currentMailbox/$totalMailboxes : $($mailbox.DisplayName)" -ForegroundColor Cyan

            try {
                # 1. Get Full Access permissions
                $fullAccessPerms = @(Get-EXOMailboxPermission -Identity $mailbox.PrimarySmtpAddress | Where-Object {
                        $_.AccessRights -contains 'FullAccess' -and
                        $_.User -notlike 'NT AUTHORITY\*' -and
                        $_.User -notlike 'S-1-*' -and
                        $_.Deny -eq $false
                    })

                foreach ($perm in $fullAccessPerms) {
                    # If UserPermission mode, only add permissions for the specified user
                    if ($isUserPermissionLookup -and $perm.User -ne $UserPermission) {
                        continue
                    }

                    $allPermissions.Add([PSCustomObject]@{
                            MailboxIdentity     = $mailbox.PrimarySmtpAddress
                            MailboxDisplayName  = $mailbox.DisplayName
                            MailboxEmail        = $mailbox.PrimarySmtpAddress
                            PermissionType      = 'Full Access'
                            User                = $perm.User
                            AccessRights        = ($perm.AccessRights -join ', ')
                            InheritanceType     = $perm.InheritanceType
                            IsInherited         = $perm.IsInherited
                            MailboxWhenCreated  = $mailbox.WhenCreated
                            MailboxWhenModified = $mailbox.WhenChanged
                        })
                }

                # 2. Get Send As permissions
                $sendAsPerms = @(Get-EXORecipientPermission -Identity $mailbox.PrimarySmtpAddress | Where-Object {
                        $_.AccessRights -contains 'SendAs' -and
                        $_.Trustee -notlike 'NT AUTHORITY\*' -and
                        $_.Trustee -notlike 'S-1-*'
                    })

                foreach ($perm in $sendAsPerms) {
                    # If UserPermission mode, only add permissions for the specified user
                    if ($isUserPermissionLookup -and $perm.Trustee -ne $UserPermission) {
                        continue
                    }

                    $allPermissions.Add([PSCustomObject]@{
                            MailboxIdentity     = $mailbox.PrimarySmtpAddress
                            MailboxDisplayName  = $mailbox.DisplayName
                            MailboxEmail        = $mailbox.PrimarySmtpAddress
                            PermissionType      = 'Send As'
                            User                = $perm.Trustee
                            AccessRights        = ($perm.AccessRights -join ', ')
                            InheritanceType     = $perm.InheritanceType
                            IsInherited         = $perm.IsInherited
                            MailboxWhenCreated  = $mailbox.WhenCreated
                            MailboxWhenModified = $mailbox.WhenChanged
                        })
                }

                # 3. Get Send on Behalf permissions
                $sendOnBehalfUsers = @($mailbox.GrantSendOnBehalfTo)
                if ($sendOnBehalfUsers -and $sendOnBehalfUsers.Count -gt 0) {
                    foreach ($user in $sendOnBehalfUsers) {
                        # If UserPermission mode, only add permissions for the specified user
                        if ($isUserPermissionLookup -and $user -ne $UserPermission) {
                            continue
                        }

                        $allPermissions.Add([PSCustomObject]@{
                                MailboxIdentity     = $mailbox.PrimarySmtpAddress
                                MailboxDisplayName  = $mailbox.DisplayName
                                MailboxEmail        = $mailbox.PrimarySmtpAddress
                                PermissionType      = 'Send on Behalf'
                                User                = $user
                                AccessRights        = 'SendOnBehalf'
                                InheritanceType     = 'None'
                                IsInherited         = $false
                                MailboxWhenCreated  = $mailbox.WhenCreated
                                MailboxWhenModified = $mailbox.WhenChanged
                            })
                    }
                }
            }
            catch {
                Write-Warning "Error processing mailbox $($mailbox.PrimarySmtpAddress): $($_.Exception.Message)"
            }
        }
    }
    end {
        if ($allPermissions.Count -gt 0) {
            if ($ExportToExcel.IsPresent) {
                $now = Get-Date -Format 'yyyy-MM-dd_HHmmss'
                $filenameSuffix = if ($UserPermission) { "User-$($UserPermission -replace '[<>:"/\\|?*]', '_')" } elseif ($ByDomain) { "Domain-$($ByDomain -replace '[<>:"/\\|?*]', '_')" } elseif ($Identity) { $Identity -replace '[<>:"/\\|?*]', '_' } else { 'AllMailboxes' }
                $excelFilePath = "$(if ($ExportPath) { $ExportPath } else { $env:userprofile })\$now-ExMailboxPermissions-$filenameSuffix.xlsx"
                Write-Host -ForegroundColor Cyan "Exporting mailbox permissions to Excel file: $excelFilePath"
                $allPermissions | Export-Excel -Path $excelFilePath -AutoSize -AutoFilter -WorksheetName 'ExchangeMailboxPermissions' -TableStyle Light9
                Write-Host -ForegroundColor Green 'Export completed successfully!'
            }
            else {
                Write-Host "`n=== PERMISSIONS SUMMARY ===" -ForegroundColor Yellow
                Write-Host "Total permissions found: $($allPermissions.Count)" -ForegroundColor Yellow

                # Group by permission type
                $groupedPerms = $allPermissions | Group-Object PermissionType
                foreach ($group in $groupedPerms) {
                    Write-Host "`n--- $($group.Name) ---" -ForegroundColor Cyan
                    $group.Group | Format-Table User, AccessRights, IsInherited -AutoSize
                }

                return $allPermissions
            }
        }
        else {
            Write-Host "`nNo permissions found." -ForegroundColor Yellow
            return $null
        }
    }
}