All scripts
Microsoft 365 216

Get-MailboxSizeReport

Reports mailbox size, item count and quota usage for every mailbox in the tenant, sorted largest first, so you can spot who is close to their limit before it becomes a support ticket.

Get-MailboxSizeReport.ps1
<#
.SYNOPSIS
    Reports mailbox size and quota usage across the tenant.

.DESCRIPTION
    Pulls mailbox statistics for every user mailbox, calculates percent of
    quota used, and sorts largest first so the mailboxes closest to their
    limit are easy to spot.

.PARAMETER WarningThresholdPercent
    Percent of quota used to flag as a warning. Defaults to 90.

.EXAMPLE
    .\Get-MailboxSizeReport.ps1 -WarningThresholdPercent 85

.NOTES
    Requires ExchangeOnlineManagement and an active Connect-ExchangeOnline session.

.AUTHOR
    Shehryar Hassan
#>

param(
    [int]$WarningThresholdPercent = 90
)

$mailboxes = Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox
$report = foreach ($mbx in $mailboxes) {
    $stats = Get-MailboxStatistics -Identity $mbx.Identity
    $usedBytes = $stats.TotalItemSize.Value.ToBytes()
    $quotaBytes = ($mbx.ProhibitSendReceiveQuota.Value).ToBytes()
    $percentUsed = if ($quotaBytes -gt 0) { [math]::Round(($usedBytes / $quotaBytes) * 100, 1) } else { 0 }

    [pscustomobject]@{
        DisplayName    = $mbx.DisplayName
        UserPrincipalName = $mbx.UserPrincipalName
        ItemCount      = $stats.ItemCount
        SizeGB         = [math]::Round($usedBytes / 1GB, 2)
        QuotaGB        = [math]::Round($quotaBytes / 1GB, 2)
        PercentUsed    = $percentUsed
        Warning        = $percentUsed -ge $WarningThresholdPercent
    }
}

$report | Sort-Object SizeGB -Descending | Format-Table -AutoSize
$report | Where-Object Warning | ForEach-Object {
    Write-Warning "$($_.DisplayName) is at $($_.PercentUsed)% of quota"
}

Read it before you run it, and test in a safe tenant first.