All scripts
Microsoft 365 611

Exchange Archive Mailbox Usage Report

Reports on which Exchange Online mailboxes have an in place archive enabled, how large the archive is, and how close it is to quota, so you can plan storage and spot mailboxes that need auto expanding archive turned on.

Get-ExchangeArchiveMailboxReport.ps1
<#
.SYNOPSIS
    Reports on Exchange Online mailboxes with an in place archive enabled.

.DESCRIPTION
    Connects to Exchange Online and checks every user mailbox for an
    enabled archive mailbox. For each one it pulls the archive size,
    item count, and quota, and flags any archive that is over 80 percent
    of its quota so you can plan storage or turn on auto expanding archive
    before someone runs out of room.

.AUTHOR
    Shehryar Hassan

.EXAMPLE
    .\Get-ExchangeArchiveMailboxReport.ps1 -OutputPath C:\Reports\ArchiveReport.csv

    Connects to Exchange Online, checks all mailboxes for archives, and
    saves the report to the given CSV path.
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $false)]
    [string]$OutputPath = ".\ExchangeArchiveMailboxReport.csv"
)

if (-not (Get-Module -ListAvailable -Name ExchangeOnlineManagement)) {
    Write-Error "The ExchangeOnlineManagement module is not installed. Run: Install-Module ExchangeOnlineManagement"
    return
}

Import-Module ExchangeOnlineManagement

try {
    Connect-ExchangeOnline -ShowBanner:$false
}
catch {
    Write-Error "Could not connect to Exchange Online. $_"
    return
}

Write-Host "Pulling mailbox list, this can take a while on larger tenants..." -ForegroundColor Cyan

$mailboxes = Get-EXOMailbox -ResultSize Unlimited -PropertySets Archive -RecipientTypeDetails UserMailbox

$results = foreach ($mailbox in $mailboxes) {

    if ($mailbox.ArchiveStatus -ne "Active") {
        [PSCustomObject]@{
            DisplayName      = $mailbox.DisplayName
            PrimarySmtp      = $mailbox.PrimarySmtpAddress
            ArchiveEnabled   = $false
            ArchiveSizeGB    = $null
            ArchiveItemCount = $null
            ArchiveQuotaGB   = $null
            PercentOfQuota   = $null
            AutoExpanding    = $mailbox.AutoExpandingArchiveEnabled
        }
        continue
    }

    $stats = Get-EXOMailboxStatistics -Identity $mailbox.PrimarySmtpAddress -Archive -ErrorAction SilentlyContinue

    $sizeGB = $null
    if ($stats -and $stats.TotalItemSize) {
        $sizeGB = [math]::Round(($stats.TotalItemSize.Value.ToBytes() / 1GB), 2)
    }

    $quotaGB = $null
    if ($mailbox.ArchiveQuota -and $mailbox.ArchiveQuota -ne "Unlimited") {
        $quotaGB = [math]::Round(($mailbox.ArchiveQuota.ToBytes() / 1GB), 2)
    }

    $percent = $null
    if ($sizeGB -and $quotaGB) {
        $percent = [math]::Round((($sizeGB / $quotaGB) * 100), 1)
    }

    [PSCustomObject]@{
        DisplayName      = $mailbox.DisplayName
        PrimarySmtp      = $mailbox.PrimarySmtpAddress
        ArchiveEnabled   = $true
        ArchiveSizeGB    = $sizeGB
        ArchiveItemCount = $stats.ItemCount
        ArchiveQuotaGB   = $quotaGB
        PercentOfQuota   = $percent
        AutoExpanding    = $mailbox.AutoExpandingArchiveEnabled
    }
}

$results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8

$nearQuota = $results | Where-Object { $_.PercentOfQuota -ge 80 }

Write-Host ""
Write-Host "Report saved to $OutputPath" -ForegroundColor Green
Write-Host "$($results.Count) mailboxes checked, $($nearQuota.Count) archives are at 80 percent of quota or higher." -ForegroundColor Yellow

if ($nearQuota.Count -gt 0) {
    $nearQuota | Format-Table DisplayName, PrimarySmtp, ArchiveSizeGB, PercentOfQuota, AutoExpanding -AutoSize
}

Disconnect-ExchangeOnline -Confirm:$false

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