How to Find Exchange Online Archive Mailboxes Close to the New 1.5 TB Limit

Just a Few Terabyte-Plus Archives in Use

Microsoft’s decision to enforce a new 1.5 TB limit for auto-expanding archives from November 1, 2021, caused more interest than I thought would happen. Although the idea of having a “bottomless archive” seems like a nice capability, the real situation is that relatively few of the 300-odd million Office 365 licensed users have archive mailboxes anywhere close to a terabyte.

Identify Large Expanding Archives with PowerShell

In the note I published on, I included a PowerShell script to report the status of archive-enabled mailboxes. Afterwards, I was asked whether it would be easy to adapt the script to report mailboxes which might be in danger of approaching the new 1.5 TB limit.

Good idea, I thought, and set to work. The full script is downloadable from GitHub, and here’s the flow of the processing.

  • Declare variables to hold the number of bytes in 1.5 TB (1649267441664) and the warning level. I selected 90% as a good warning threshold. You could select a lower or higher value.
  • Find the mailboxes with archives. This is a server-side filter with Get-ExoMailbox, so it’s reasonably fast. I then use a client-side filter to remove mailboxes which don’t use expandable archives.
  • Calculate the mailbox size. In this instance, Microsoft is taking an all-up approach and will assess the 1.5 TB limit against the complete mailbox contents, including Recoverable Items. This is unlike normal mailbox storage quotas, which only count “non-dumpster” folders.
  • Check if each mailbox is within the warning limit and create a status message if true.
  • I wanted some way to assess of the daily growth rate for the archive. There’s no obvious way to generate this figure from PowerShell, so I use the creation date for the mailbox to calculate the number of days in use. I then divide the number of days into the current archive size to calculate the average daily growth. It’s a crude mechanism but better than nothing.
  • I also use the average daily growth to estimate the number of days until the archive hits the limit. For most mailboxes, this is a big number.

Here’s the main processing loop for the mailboxes:

$Report = [System.Collections.Generic.List[Object]]::new()
ForEach ($M in $ExMbx) {
   $Status = $Null
   Write-Host "Processing mailbox" $M.DisplayName
   [int]$DaysSinceCreation = ((New-TimeSpan -Start ($M.WhenCreated) -End ($Now)).Days)
   $Stats = Get-ExoMailboxStatistics -Archive -Identity $M.UserPrincipalName
   [string]$ArchiveSize = $Stats.TotalItemSize.Value
   [string]$DeletedArchiveItems = $Stats.TotalDeletedItemSize.Value 
   [long]$BytesInArchive = $Stats.TotalItemSize.Value.ToBytes()
   [long]$BytesInRecoverableItems = $Stats.TotalDeletedItemSize.Value.ToBytes()
   [long]$TotalBytesInArchive = $BytesInArchive + $BytesInRecoverableItems
   # Check if archive size is within 10% of the 1.5 TB limit - the size that counts is the combination of Recoverable Items and normal folders
   If ($TotalBytesInArchive -ge $TBBytesWarning) 
       { Write-Host ("Archive size {0} for {1} is within 10% of 1.5 TB limit" -f $ArchiveSize, $M.DisplayName ) 
         $Status = "Archive within 10% of 1.5 TB limit" }
   [long]$BytesPerDay = $TotalBytesInArchive/$DaysSinceCreation
   [long]$NumberDaysLeft = (($TBBytes - $TotalBytesInArchive)/$BytesPerDay)
   $BytesPerDayMB = $BytesPerDay/1MB
   $GrowthRateDay = [math]::Round($BytesPerDayMB,4)
   $TotalArchiveSizeGB = [math]::Round(($TotalBytesInArchive/1GB),2) 
   $ReportLine = [PSCustomObject][Ordered]@{  
       Mailbox                   = $M.DisplayName
       UPN                       = $M.UserPrincipalName
       Created                   = $M.WhenCreated
       Days                      = $DaysSinceCreation
       Type                      = $M.RecipientTypeDetails
       "Archive Quota"           = $M.ArchiveQuota.Split("(")[0] 
       "Archive Status"          = $M.ArchiveStatus
       "Archive Size"            = $ArchiveSize.Split("(")[0] 
       "Archive Items"           = $Stats.ItemCount
       "Deleted Archive Items Size" = $DeletedArchiveItems.Split("(")[0] 
       "Deleted Items"           = $Stats.DeletedItemCount
       "Total Archive Size (GB)" = $TotalArchiveSizeGB
       "Daily Growth Rate (MB)"  = $GrowthRateDay
       "Days Left to Limit"      = $NumberDaysLeft
       Status                    = $Status   
} #End ForEach

Considering the Data

The script generates a CSV file containing the mailbox data. I also like to output the data on screen using the Out-GridView cmdlet to get some insight into the results. For example, Figure 1 shows some output from mailboxes in my tenant. As you can see, at a 18.07 MB/day growth rate, it will take my archive 84,228 days to get from its current 9.129 GB to 1.5 TB. What a relief!

Some archive mailboxes will take a long time to reach the 1.5 TB limit
Figure 1: Some archive mailboxes will take a long time to reach the 1.5 TB limit

Example of PowerShell Flexibility

The script works as an example of how PowerShell delivers insight for Microsoft 365 tenant administrators, which is why every tenant administrator should be familiar with PowerShell and be able to run scripts and make simple code changes. Because most archives are less than 100 GB and won’t get near the new 1.5 TB limit in their lifetime, I suspect that few tenants will find the script valuable in an operational sense. However, it’s always nice to be able to answer questions with a few lines of code.

Learn more about how Office 365 really works (including PowerShell and archive mailboxes) on an ongoing basis by subscribing to the Office 365 for IT Pros eBook. Our monthly updates keep subscribers informed about what’s important across the Office 365 ecosystem.

8 Replies to “How to Find Exchange Online Archive Mailboxes Close to the New 1.5 TB Limit”

  1. Thanks for sharing!
    I tried the script right out of the box and it threw an error:

    Get-OrganizationConfig : The term ‘Get-OrganizationConfig’ is not recognized as the name of a cmdlet, function, script
    file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct a
    nd try again.
    At C:\Temp2\ReportAutoExpandingArchives.PS1:7 char:7
    + If (((Get-OrganizationConfig).AutoExpandingArchiveEnabled) -ne $True) …
    + ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (Get-OrganizationConfig:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    Get-ExoMailbox : No valid token was found in the cache, please run Connect-ExchangeOnline.
    At C:\Temp2\ReportAutoExpandingArchives.PS1:11 char:15
    + … rray]$Mbx = Get-ExoMailbox -RecipientTypeDetails SharedMailbox, UserM …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ProtocolError:  ) [Get-EXOMailbox], AuthenticationException
    + FullyQualifiedErrorId : No valid token was found in the cache, please run Connect-ExchangeOnline.,Microsoft.Exch

    1. You need to connect to Exchange Online. I added this line to the script in GitHub:
      $Modules = Get-Module
      If (“ExchangeOnlineManagement” -notin $Modules.Name) {Write-Host “Please connect to Exchange Online Management before continuing…”;break}

  2. when trying to run via ISE, I get told “Expanding archives are not enabled in this tenant” – they most definitely are though!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.