Microsoft 365 Mailbox Quota Management with PowerShell

Disclaimer: Some content in this article may be AI-generated and might not be fully accurate. Please double-check any critical information, or reach out to us if you have questions or find any issues.

Default Exchange Online quotas are generous, but eventually someone fills up their mailbox and you get the "mailbox is full" error. PowerShell gives you the tools to monitor usage, set custom quotas, and generate reports before users start complaining.

TL;DR

  • Connect: Connect-ExchangeOnline
  • Check size: Get-MailboxStatistics
  • Set quota: Set-Mailbox -ProhibitSendQuota
  • Report: Export to CSV for analysis
  • Archive: Enable auto-expanding archives
  • Monitor: Set up alerts for approaching limits

Connect to Exchange Online

# Install if needed
Install-Module ExchangeOnlineManagement

# Connect
Connect-ExchangeOnline -UserPrincipalName [email protected]

Check Mailbox Size and Usage

Get basic mailbox statistics:

Get-MailboxStatistics -Identity "[email protected]"

This shows ItemCount, TotalItemSize, and LastLogonTime.

Get detailed size information:

Get-MailboxStatistics -Identity "[email protected]" | Select-Object DisplayName, ItemCount, TotalItemSize, TotalDeletedItemSize

Check Current Quota Settings

View mailbox quotas:

Get-Mailbox -Identity "[email protected]" | Select-Object ProhibitSendQuota, ProhibitSendReceiveQuota, IssueWarningQuota

Default quotas for Exchange Online Plan 2:

  • ProhibitSendQuota: 99GB
  • ProhibitSendReceiveQuota: 100GB
  • IssueWarningQuota: 98GB

Set Custom Mailbox Quotas

Increase quota for a specific user:

Set-Mailbox -Identity "[email protected]" -ProhibitSendQuota 150GB -ProhibitSendReceiveQuota 155GB -IssueWarningQuota 145GB

Set lower quota for a user:

Set-Mailbox -Identity "[email protected]" -ProhibitSendQuota 10GB -ProhibitSendReceiveQuota 11GB -IssueWarningQuota 9GB

Set unlimited quota (careful with this):

Set-Mailbox -Identity "[email protected]" -ProhibitSendQuota unlimited -ProhibitSendReceiveQuota unlimited

Bulk Quota Management

Set quotas for all users in a department:

Get-Mailbox -Filter "Department -eq 'Executives'" | Set-Mailbox -ProhibitSendQuota 150GB -ProhibitSendReceiveQuota 155GB

Set different quotas based on job title:

$executives = Get-Mailbox -Filter "Title -like '*VP*' -or Title -like '*Director*' -or Title -like '*Manager*'"
$regularUsers = Get-Mailbox | Where-Object {$executives.Identity -notcontains $_.Identity}

$executives | Set-Mailbox -ProhibitSendQuota 100GB -ProhibitSendReceiveQuota 105GB
$regularUsers | Set-Mailbox -ProhibitSendQuota 50GB -ProhibitSendReceiveQuota 55GB

Mailbox Size Reporting

Generate a report of all mailbox sizes:

$mailboxes = Get-Mailbox -ResultSize Unlimited
$report = @()

foreach ($mailbox in $mailboxes) {
    $stats = Get-MailboxStatistics -Identity $mailbox.UserPrincipalName
    $quota = Get-Mailbox -Identity $mailbox.UserPrincipalName
    
    $report += [PSCustomObject]@{
        DisplayName = $mailbox.DisplayName
        UserPrincipalName = $mailbox.UserPrincipalName
        ItemCount = $stats.ItemCount
        TotalSizeGB = [math]::Round(($stats.TotalItemSize.Value.ToBytes() / 1GB), 2)
        ProhibitSendQuotaGB = [math]::Round(($quota.ProhibitSendQuota.Value.ToBytes() / 1GB), 2)
        PercentUsed = [math]::Round((($stats.TotalItemSize.Value.ToBytes() / $quota.ProhibitSendQuota.Value.ToBytes()) * 100), 1)
    }
}

$report | Sort-Object PercentUsed -Descending | Export-Csv "C:\Temp\MailboxSizes.csv" -NoTypeInformation

Find Mailboxes Near Quota Limits

Find users approaching their limits:

$mailboxes = Get-Mailbox -ResultSize Unlimited
$nearQuota = @()

foreach ($mailbox in $mailboxes) {
    $stats = Get-MailboxStatistics -Identity $mailbox.UserPrincipalName
    $quota = Get-Mailbox -Identity $mailbox.UserPrincipalName
    
    if ($stats.TotalItemSize.Value -gt ($quota.IssueWarningQuota.Value * 0.9)) {
        $nearQuota += [PSCustomObject]@{
            DisplayName = $mailbox.DisplayName
            Email = $mailbox.UserPrincipalName
            CurrentSizeGB = [math]::Round(($stats.TotalItemSize.Value.ToBytes() / 1GB), 2)
            QuotaGB = [math]::Round(($quota.ProhibitSendQuota.Value.ToBytes() / 1GB), 2)
            PercentUsed = [math]::Round((($stats.TotalItemSize.Value.ToBytes() / $quota.ProhibitSendQuota.Value.ToBytes()) * 100), 1)
        }
    }
}

$nearQuota | Sort-Object PercentUsed -Descending | Format-Table

Enable Auto-Expanding Archives

For users with large mailboxes, enable auto-expanding archives:

Enable-Mailbox -Identity "[email protected]" -AutoExpandingArchive

Check archive status:

Get-Mailbox -Identity "[email protected]" | Select-Object ArchiveStatus, AutoExpandingArchiveEnabled

Get archive statistics:

Get-MailboxStatistics -Identity "[email protected]" -Archive

Shared Mailbox Quotas

Shared mailboxes have different quotas. Check current settings:

Get-Mailbox -Identity "[email protected]" | Select-Object ProhibitSendQuota, ProhibitSendReceiveQuota

Set custom quota for shared mailbox:

Set-Mailbox -Identity "[email protected]" -ProhibitSendQuota 25GB -ProhibitSendReceiveQuota 30GB

Retention Policies and Auto-Cleanup

Apply retention policy to move old items to archive:

Set-Mailbox -Identity "[email protected]" -RetentionPolicy "Default Archive and Retention Policy"

Enable automatic deletion of items in Deleted Items:

Set-Mailbox -Identity "[email protected]" -RetainDeletedItemsFor 30

Common Issues and Solutions

"The mailbox size limit has been reached"

  • Increase quota or enable auto-expanding archive
  • Delete unnecessary items or move to archive
  • Check if retention policy is moving items properly

Quota changes don't take effect

  • Changes can take 5-15 minutes to propagate
  • Restart Outlook to refresh settings
  • Check the command syntax and values

Archive not working

  • Verify archive is enabled: Get-Mailbox | Select AutoExpandingArchiveEnabled
  • Check retention policy is applied
  • May take time for items to move

Best Practices

  • Monitor regularly: Run size reports monthly
  • Set appropriate quotas: Don't give everyone unlimited space
  • Enable archives: For users over 50GB
  • Implement retention: Move old items automatically
  • Plan for growth: Set quotas with future needs in mind

Quick Reference

# Connect
Connect-ExchangeOnline

# Check mailbox size
Get-MailboxStatistics -Identity "[email protected]" | Select ItemCount, TotalItemSize

# Check quotas
Get-Mailbox -Identity "[email protected]" | Select ProhibitSendQuota, IssueWarningQuota

# Set custom quota
Set-Mailbox -Identity "[email protected]" -ProhibitSendQuota 50GB -IssueWarningQuota 45GB

# Generate size report
Get-Mailbox | Get-MailboxStatistics | Select DisplayName, @{Name="SizeGB";Expression={[math]::Round(($_.TotalItemSize.Value.ToBytes()/1GB),2)}} | Sort SizeGB -Descending

# Enable auto-expanding archive
Enable-Mailbox -Identity "[email protected]" -AutoExpandingArchive

Mailbox quotas seem simple until you have 200 users and need to manage storage across different departments. PowerShell makes it manageable and gives you the reporting you need to plan for future storage requirements.

Need Help with Microsoft 365 Mailbox Management?

Mailbox quotas, storage management, and archive configuration are critical for maintaining efficient email systems. My company NHM Ohio provides comprehensive Microsoft 365 administration services to optimize your mailbox storage and prevent quota issues.

Whether you need quota management, archive setup, or storage optimization, explore our Microsoft 365 services or contact us for assistance.