Back to script library
Entra / Microsoft 365 · Exchange Online

Report mailbox permissions mailboxes

Quick and simple script to generate a report of non-standard permissions applied to Exchange Online user and shared mailboxes.

Connect & set up

Run these once per session. All scopes are read-only unless the script makes changes.

Connect-ExchangeOnline -ShowBanner:$false

Run it

The main script. Copy it, or download the .ps1 and run it from your console.

Clear-Host
[array]$Modules = Get-Module | Select-Object -ExpandProperty Name
If ("ExchangeOnlineManagement" -notin $Modules) {
Write-Host "Connecting to Exchange Online management module..."
Connect-ExchangeOnline -ShowBanner:$false
}
Write-Host "Fetching mailboxes"
[array]$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox, SharedMailbox -ResultSize Unlimited -PropertySet Delivery -Properties RecipientTypeDetails, DisplayName | Select-Object DisplayName, UserPrincipalName, RecipientTypeDetails, GrantSendOnBehalfTo
If ($Mbx.Count -eq 0) {
Write-Error "No mailboxes found. Script exiting..."
Break
}
Clear-Host
$Report = [System.Collections.Generic.List[Object]]::new() # Create output file
$ProgressDelta = 100/($Mbx.count); $PercentComplete = 0; $MbxNumber = 0
ForEach ($M in $Mbx) {
$MbxNumber++
$MbxStatus = $M.DisplayName + " ["+ $MbxNumber +"/" + $Mbx.Count + "]"
Write-Progress -Activity "Checking permissions for mailbox" -Status $MbxStatus -PercentComplete $PercentComplete
$PercentComplete += $ProgressDelta
$Permissions = Get-ExoRecipientPermission -Identity $M.UserPrincipalName | Where-Object {$_.Trustee -ne "NT AUTHORITY\SELF"}
If ($null -ne $Permissions) {
# Grab information about SendAs permission and output it into the report
ForEach ($Permission in $Permissions) {
$ReportLine = [PSCustomObject] @{
Mailbox = $M.DisplayName
UPN = $M.UserPrincipalName
Permission = $Permission | Select-Object -ExpandProperty AccessRights
AssignedTo = $Permission.Trustee
MailboxType = $M.RecipientTypeDetails
}
$Report.Add($ReportLine)
}
}
# Grab information about FullAccess permissions
$Permissions = Get-ExoMailboxPermission -Identity $M.UserPrincipalName | Where-Object {$_.User -Like "*@*" }
If ($null -ne $Permissions) {
# Grab each permission and output it into the report
ForEach ($Permission in $Permissions) {
$ReportLine = [PSCustomObject] @{
Mailbox = $M.DisplayName
UPN = $M.UserPrincipalName
Permission = $Permission | Select-Object -ExpandProperty AccessRights
AssignedTo = $Permission.User
MailboxType = $M.RecipientTypeDetails
}
$Report.Add($ReportLine)
}
}
# Check if this mailbox has granted Send on Behalf of permission to anyone
If (![string]::IsNullOrEmpty($M.GrantSendOnBehalfTo)) {
ForEach ($Permission in $M.GrantSendOnBehalfTo) {
$ReportLine = [PSCustomObject] @{
Mailbox = $M.DisplayName
UPN = $M.UserPrincipalName
Permission = "Send on Behalf Of"
AssignedTo = (Get-ExoRecipient -Identity $Permission).PrimarySmtpAddress
MailboxType = $M.RecipientTypeDetails
}
$Report.Add($ReportLine) }}
# Short delay to prevent throttling errors that will likely be met when processing thousands of mailboxes
Start-Sleep -Milliseconds 250
}
$Report | Sort-Object -Property @{Expression = {$_.MailboxType}; Ascending= $False}, Mailbox | Export-CSV c:\temp\MailboxAccessPermissions.csv -NoTypeInformation
Write-Host "All done." $Mbx.Count "mailboxes scanned. Report of send permissions available in c:\temp\MailboxAccessPermissions.csv"
$Report | Out-GridView
Attribution