Exchange Online security

How to find orphaned mailbox permissions in Exchange Online

List Full Access and Send As entries held by deleted accounts with Exchange Online PowerShell, check a leaver's mailboxes in the admin centre, or run Altivane's Orphaned Permissions report.

By the Published

To find orphaned mailbox permissions in Exchange Online, read each mailbox's Full Access entries with Get-MailboxPermission -IncludeUnresolvedPermissions and the Send As entries with Get-EXORecipientPermission, then keep the entries held by a security identifier (SID) rather than a name. Get-EXOMailboxPermission has no switch for unresolved entries, so it is not the cmdlet for this, and a SID no longer says who the person was.

Choose the method that fits the job
MethodBest fit
PowerShellA CSV of Full Access and Send As entries still held by deleted accounts in 1 tenant.
Admin centreChecking 1 mailbox's delegation after a leaver, against the Deleted users list.
AltivaneRecommended for regular permission clean-ups, with calendar entries included and a workbook to keep.

Before you start

Use an account in a role group that can read mailbox settings. Microsoft lists Organization Management and Recipient Management for mailbox settings in Exchange Online, and says members of View-Only Management can view the configuration of those features.

A permission is orphaned when the account it was given to is gone: the entry stays on the mailbox, and Exchange can no longer resolve it to a recipient. The script reads permissions as they are when it runs and keeps direct, allowed entries only. It covers Full Access and Send As; calendar folders and Send on behalf are not read. The examples read and export; they remove no permission and change nothing.

Option 1

Find orphaned mailbox permissions with PowerShell

Install the module once, then connect and export every Full Access and Send As entry whose trustee is a SID. It reads 1 mailbox at a time, so a large tenant takes a while.

PowerShell
# Install once, if the module is not already installed.
Install-Module ExchangeOnlineManagement -Scope CurrentUser
PowerShell
$ErrorActionPreference = 'Stop'
$sid = '^S-1-\d+(-\d+)+$'
Connect-ExchangeOnline -ShowBanner:$false
try {
    $report = [System.Collections.Generic.List[object]]::new()
    foreach ($mailbox in Get-EXOMailbox -ResultSize Unlimited) {
        $identity = $mailbox.UserPrincipalName
        if (-not $identity) { throw "No user principal name for $($mailbox.DisplayName)." }
        $entries = Get-MailboxPermission -Identity $identity -IncludeUnresolvedPermissions
        foreach ($entry in $entries) {
            $direct = -not $entry.IsInherited -and -not $entry.Deny
            if ($direct -and "$($entry.User)" -match $sid) {
                $report.Add([pscustomobject]@{
                    Mailbox = $mailbox.PrimarySmtpAddress.ToString()
                    Permission = 'Full Access'
                    Trustee = "$($entry.User)"
                    AccessRights = ($entry.AccessRights -join ', ')
                })
            }
        }
    }
    foreach ($entry in Get-EXORecipientPermission -AccessRights SendAs -ResultSize Unlimited) {
        $direct = -not $entry.IsInherited -and $entry.AccessControlType -ne 'Deny'
        if ($direct -and "$($entry.Trustee)" -match $sid) {
            $report.Add([pscustomobject]@{
                Mailbox = "$($entry.Identity)"
                Permission = 'Send As'
                Trustee = "$($entry.Trustee)"
                AccessRights = ($entry.AccessRights -join ', ')
            })
        }
    }
    if ($report.Count -eq 0) {
        Write-Output 'No Full Access or Send As entry is held by a deleted account.'
    } else {
        $report | Sort-Object Mailbox, Permission |
            Export-Csv -Path './orphaned-permissions.csv' -NoTypeInformation -Encoding utf8
        Write-Output "$($report.Count) orphaned permissions exported."
    }
} finally {
    Disconnect-ExchangeOnline -Confirm:$false
}

The CSV has 1 row for each orphaned entry, with the mailbox, the permission, the SID and the rights. To narrow it to shared mailboxes, add -RecipientTypeDetails SharedMailbox to Get-EXOMailbox. The script stops on a blank user principal name, because a blank -Identity returns every mailbox's permissions.

Check a single mailbox

Reconnect with Connect-ExchangeOnline, then read 1 mailbox with its unresolved entries. The export above disconnects when it finishes.

PowerShell
# Run while connected to Exchange Online. Replace the example mailbox.
Get-MailboxPermission -Identity 'shared@example.com' -IncludeUnresolvedPermissions |
    Where-Object { -not $_.IsInherited } |
    Select-Object Identity, User, AccessRights, Deny

A row whose User starts with S-1- is an entry left by an account Exchange can no longer find.

Option 2

Check mailbox delegation in the admin centre

  1. Sign in to the Microsoft 365 admin centre for the correct tenant and go to Users > Deleted users to see who was deleted in the last 30 days.
  2. Open the Exchange admin centre and go to Recipients > Mailboxes.
  3. Select a mailbox the leaver used, such as a shared mailbox, and select Mailbox delegation.
  4. Read the names under Read and manage (Full Access), Send As and Send on behalf, and compare them with the deleted users.
  5. Close the pane without choosing Edit, so nothing changes.

This suits checking a few mailboxes after an offboarding. It does not suit a tenant-wide search, since the admin centre shows 1 mailbox at a time and lists no orphaned entries on their own.

Common questions

Why does Get-EXOMailboxPermission show no orphaned entries?

Its parameters have no switch for unresolved permissions. Get-MailboxPermission has -IncludeUnresolvedPermissions, which returns them, so the script uses it for Full Access even though Microsoft recommends the EXO cmdlets elsewhere.

Why is a person deleted last week not listed?

For 30 days after deletion the mailbox is soft-deleted and can still be restored. Get-MailboxPermission returns permissions held by soft-deleted mailbox users only when you add -IncludeSoftDeletedUserPermissions, so run the single mailbox check with that switch to see them.

Where are the permissions held by people who still exist?

The script keeps only entries held by SIDs. To export every Full Access grant, see how to export mailbox permissions in Exchange Online, and for Send As, how to export Send As permissions.

Microsoft references

Technical references checked on 6 November 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.

Talk to us about Altivane

Questions, or pricing? Get in touch.

Contact us