All scripts
Governance 576
Export-SharedMailboxPermissionsReport
A PowerShell script that reports on shared mailbox sizes and permissions in Exchange Online, so you can spot large mailboxes or unexpected access before they cause problems.
Export-SharedMailboxPermissionsReport.ps1
<#
.SYNOPSIS
Reports on shared mailboxes in Exchange Online, including size and who has Full Access or Send As permissions.
.DESCRIPTION
Connects to Exchange Online and loops through every shared mailbox in the tenant. For each one it
pulls the mailbox size, item count, and a list of users with Full Access or Send As rights. This is
useful for spotting shared mailboxes that have grown too large, or that have more people with access
than expected. Results are exported to a CSV file so they are easy to review or hand off.
.PARAMETER OutputPath
Path to the CSV file that the report is written to. Defaults to a timestamped file in the current folder.
.EXAMPLE
.\Export-SharedMailboxPermissionsReport.ps1
Connects to Exchange Online, prompts for sign in if needed, and writes a report to
SharedMailboxPermissionsReport-<date>.csv in the current folder.
.EXAMPLE
.\Export-SharedMailboxPermissionsReport.ps1 -OutputPath C:\Reports\shared-mailboxes.csv
Writes the report to a specific path instead of the default location.
.AUTHOR
Shehryar Hassan
#>
[CmdletBinding()]
param(
[string]$OutputPath = "SharedMailboxPermissionsReport-$(Get-Date -Format 'yyyy-MM-dd').csv"
)
if (-not (Get-Module -ListAvailable -Name ExchangeOnlineManagement)) {
Write-Error "The ExchangeOnlineManagement module is not installed. Run: Install-Module ExchangeOnlineManagement"
return
}
Import-Module ExchangeOnlineManagement
$existingSession = Get-ConnectionInformation -ErrorAction SilentlyContinue
if (-not $existingSession) {
Connect-ExchangeOnline -ShowBanner:$false
}
Write-Host "Getting shared mailboxes..."
$sharedMailboxes = Get-EXOMailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$report = foreach ($mailbox in $sharedMailboxes) {
Write-Host "Checking $($mailbox.PrimarySmtpAddress)"
$stats = Get-EXOMailboxStatistics -Identity $mailbox.PrimarySmtpAddress
$sizeMB = 0
if ($stats.TotalItemSize) {
$sizeText = $stats.TotalItemSize.ToString()
if ($sizeText -match '\(([\d,]+)\s+bytes\)') {
$sizeMB = [math]::Round(($matches[1] -replace ',', '') / 1MB, 0)
}
}
$fullAccessUsers = Get-EXOMailboxPermission -Identity $mailbox.PrimarySmtpAddress |
Where-Object { $_.AccessRights -contains "FullAccess" -and -not $_.IsInherited -and $_.User -notlike "NT AUTHORITY\SELF" } |
Select-Object -ExpandProperty User
$sendAsUsers = Get-EXORecipientPermission -Identity $mailbox.PrimarySmtpAddress |
Where-Object { $_.AccessRights -contains "SendAs" -and $_.Trustee -notlike "NT AUTHORITY\SELF" } |
Select-Object -ExpandProperty Trustee
[PSCustomObject]@{
DisplayName = $mailbox.DisplayName
PrimarySmtp = $mailbox.PrimarySmtpAddress
ItemCount = $stats.ItemCount
SizeMB = $sizeMB
FullAccessUsers = ($fullAccessUsers -join "; ")
SendAsUsers = ($sendAsUsers -join "; ")
FullAccessCount = @($fullAccessUsers).Count
}
}
$report | Sort-Object -Property SizeMB -Descending | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Report saved to $OutputPath"
Write-Host "$($report.Count) shared mailboxes checked."
$largeMailboxes = $report | Where-Object { $_.SizeMB -gt 40000 }
if ($largeMailboxes) {
Write-Warning "$($largeMailboxes.Count) shared mailbox(es) are over 40 GB and close to the 50 GB free size limit."
}
Read it before you run it, and test in a safe tenant first.