🚀 Executive Summary
TL;DR: Auditing Office 365 shared mailbox permissions is complex due to distributed permission types like FullAccess, SendAs, and SendOnBehalf, which the M365 Admin Center cannot fully track. This guide provides three PowerShell scripts to efficiently audit permissions for individual users, generate comprehensive reports for all shared mailboxes, and identify delegate access on user mailboxes, ensuring compliance and mitigating security risks.
🎯 Key Takeaways
- Office 365 shared mailbox permissions are distributed across `FullAccess`, `SendAs`, and `SendOnBehalf` types, making the M365 Admin Center inadequate for comprehensive auditing.
- `SendAs` permissions are critical for security, as they allow users to send emails appearing directly from a shared mailbox, potentially bypassing standard account access controls.
- PowerShell is essential for accurate auditing, offering scripts to find specific user `FullAccess`, generate comprehensive `FullAccess` and `SendAs` reports for all shared mailboxes, and identify delegate access on user mailboxes.
- Filtering out system accounts (`NT AUTHORITY\*`) and inherited permissions (`IsInherited -eq $false`) is crucial for creating clean, actionable audit reports.
Struggling to track Office 365 shared mailbox permissions? This guide offers three battle-tested PowerShell scripts to quickly audit who has access to what, saving you from compliance headaches and security risks.
Who Has the Keys? A No-BS Guide to Auditing Shared Mailbox Access
I still remember the Friday afternoon scramble. We got an urgent ticket from HR: “Immediate offboarding for user ‘acme-user-01’. Terminated, effective now. Revoke all access.” We ran the standard playbook: disabled the account, reset the password, revoked sessions, removed group memberships. We thought we were done. Then, Monday morning, our Head of Finance storms over to my desk. A critical vendor payment email was sent from the invoicing@techresolve.com shared mailbox, and the logs showed it came from the terminated employee’s credentials, likely cached on a personal device. How? Simple. We revoked his access *to his account*, but we never checked the `SendAs` permissions granted directly on the shared mailbox. It was a painful lesson in why you can’t trust the GUI and why you need a reliable way to see the whole permissions picture.
Why Is This So Hard? The Root of the Problem
You’d think a simple question like “Who can access this mailbox?” would have a simple answer in the M365 Admin Center. But it’s a classic case of distributed permissions. Access isn’t a single switch; it’s a tangled web of different permission types that live in different places:
- FullAccess: This lets a user open the mailbox and act as the mailbox owner. It’s often paired with “Automapping,” which automatically adds the mailbox to the user’s Outlook profile—a feature that can cause its own set of problems.
- SendAs: This allows a user to send email that appears to come directly from the shared mailbox address. The recipient has no idea it was sent by a delegate. This was the permission that bit us in my story.
- SendOnBehalf: This allows a user to send email on behalf of the mailbox. The recipient sees “Darian Vance on behalf of Invoicing,” making it more transparent.
The Admin GUI is fine for one-off changes, but for an audit? It’s useless. You need to drop into PowerShell to get the ground truth.
Solution 1: The Quick Fix for a Single User
This is my go-to for simple helpdesk tickets. A manager asks, “What access does Jane Doe have so I can mirror it for the new hire?” Instead of clicking through a dozen mailboxes, you run this. It finds all mailboxes where a specific user has explicit `FullAccess` permissions.
The Script:
# First, make sure you're connected to Exchange Online PowerShell
# Connect-ExchangeOnline
$UserToCheck = "jane.doe@techresolve.com"
Write-Host "Checking FullAccess permissions for: $UserToCheck" -ForegroundColor Yellow
Get-Mailbox -ResultSize Unlimited | Get-MailboxPermission -User $UserToCheck | Select-Object Identity, User, @{Name='AccessRights';Expression={[string]::join(', ', $_.AccessRights)}}
This is fast and effective for a targeted request. It pipes all mailboxes into Get-MailboxPermission and filters for just the user you care about. It’s a scalpel, not a sledgehammer.
Solution 2: The Comprehensive Audit (The Right Way)
Okay, now it’s audit season. A compliance officer needs a complete report of every user who has access to every shared mailbox, and they need it by end-of-day. This is where you need to get serious. The goal here is to generate a clean CSV file that you can hand off to non-technical folks.
The Script:
# Connect-ExchangeOnline
$SharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$PermissionsReport = @()
Write-Host "Found $($SharedMailboxes.Count) shared mailboxes. Auditing permissions..." -ForegroundColor Green
foreach ($Mailbox in $SharedMailboxes) {
# Get FullAccess permissions
$FullAccessPermissions = Get-MailboxPermission -Identity $Mailbox.Identity | Where-Object { ($_.User -notlike "NT AUTHORITY\*") -and ($_.IsInherited -eq $false) }
foreach ($Permission in $FullAccessPermissions) {
$PermissionsReport += [PSCustomObject]@{
Mailbox = $Mailbox.DisplayName
User = $Permission.User
Permission = "FullAccess"
UserIsGroup = (Get-Recipient -Identity $Permission.User).RecipientType -like "*Group*"
}
}
# Get SendAs permissions
$SendAsPermissions = Get-RecipientPermission -Identity $Mailbox.Identity | Where-Object { ($_.Trustee -notlike "NT AUTHORITY\*") -and ($_.IsInherited -eq $false) }
foreach ($Permission in $SendAsPermissions) {
$PermissionsReport += [PSCustomObject]@{
Mailbox = $Mailbox.DisplayName
User = $Permission.Trustee
Permission = "SendAs"
UserIsGroup = (Get-Recipient -Identity $Permission.Trustee).RecipientType -like "*Group*"
}
}
}
Write-Host "Audit complete. Exporting to CSV."
$PermissionsReport | Export-Csv -Path ".\SharedMailboxPermissions_Audit.csv" -NoTypeInformation
Pro Tip: Notice the
Where-Objectclauses? I’m filtering out default system accounts like “NT AUTHORITY\SELF” and inherited permissions. This cleans up the noise so you only see permissions that were explicitly granted by an admin.
This script iterates through every single shared mailbox, checks both FullAccess and SendAs permissions, and compiles it all into one neat report. It even adds a column to tell you if the permission was granted to a user directly or via a mail-enabled security group.
Solution 3: The ‘Nuclear’ Option – Finding All Delegate Access
Sometimes the problem is deeper than shared mailboxes. You discover a culture of users just granting delegate access to their own personal mailboxes. This is a security and data governance nightmare. An employee goes on vacation and grants their manager `FullAccess` to their entire mailbox instead of using a proper shared resource. Now what? You need to find it all.
The Script:
# Connect-ExchangeOnline
# WARNING: This can be VERY slow on large tenants.
Write-Host "Starting a comprehensive delegate audit on ALL mailboxes. This may take a while..." -ForegroundColor Red
Get-Mailbox -ResultSize Unlimited -Filter {RecipientTypeDetails -eq 'UserMailbox'} | Get-MailboxPermission | Where-Object {
($_.User -notlike "NT AUTHORITY\*") -and `
($_.IsInherited -eq $false) -and `
($_.User -ne $_.Identity.ToString()) # Filter out the user's own permission on their mailbox
} | Select-Object Identity, User, AccessRights | Export-Csv -Path ".\All_UserMailbox_Delegates.csv" -NoTypeInformation
Write-Host "Delegate audit complete." -ForegroundColor Green
Warning: Run this with caution. On a tenant with thousands of mailboxes, this script will take a significant amount of time and generate a lot of data. It’s not for your daily check-up; it’s for when you need to do a deep, comprehensive cleanup of bad practices.
This script ignores shared mailboxes and goes straight for the user mailboxes, pulling every explicitly granted permission. It’s the ultimate tool for finding those hidden, ad-hoc access grants that bypass all your standard procedures. When you run this, be prepared for some surprising and frankly, terrifying, results.
🤖 Frequently Asked Questions
âť“ How can I effectively audit shared mailbox permissions in Office 365?
To effectively audit shared mailbox permissions, use PowerShell scripts. The article provides scripts to check `FullAccess` for a single user, generate a comprehensive report of `FullAccess` and `SendAs` permissions for all shared mailboxes, and identify delegate access on user mailboxes.
âť“ What are the key differences between `FullAccess`, `SendAs`, and `SendOnBehalf` permissions?
`FullAccess` allows a user to open and act as the mailbox owner. `SendAs` permits sending emails that appear directly from the mailbox address, concealing the sender. `SendOnBehalf` allows sending emails on behalf of the mailbox, transparently showing the delegate.
âť“ What is a common pitfall when auditing shared mailbox access and how can it be avoided?
A common pitfall is neglecting `SendAs` permissions, which can allow unauthorized sending even after an account is disabled. This can be avoided by using comprehensive PowerShell scripts that explicitly audit both `FullAccess` and `SendAs` permissions, filtering out system and inherited entries for clarity.
Leave a Reply