Dec 13, 2025

Finding the Real Creation Date of Any Exchange Mailbox with PowerShell

3 min readIntermediate

“When was this mailbox actually created” comes up more often than you’d expect, in offboarding audits, license reconciliation, and the occasional “how long has this account existed” security question. The tricky part is that Exchange tracks two different dates that both sound like the answer, and using the wrong one gives you a subtly incorrect report.

The two dates that both look right, and only one is

  • WhenCreated on the mailbox/user object reflects when the underlying Active Directory (or Entra ID) object was created, which is often earlier than the mailbox itself, if the account existed before it was mailbox-enabled.
  • WhenMailboxCreated, found on mailbox statistics rather than the mailbox object itself, reflects the actual date the mailbox database entry was created, which is the true “mailbox creation date” in the way most people mean the question.

Getting this distinction right matters most when reporting on migrated mailboxes, since a cross-forest or tenant-to-tenant migration can create a new mailbox with a fresh WhenMailboxCreated date while the user object’s WhenCreated date is years older.

On-premises Exchange Server

Get-MailboxStatistics -Identity "[email protected]" | Select-Object DisplayName, WhenMailboxCreated, WhenCreated, DatabaseName

For an organization-wide report:

Get-Mailbox -ResultSize Unlimited | ForEach-Object {
    Get-MailboxStatistics -Identity $_.Identity | Select-Object DisplayName, WhenMailboxCreated
} | Export-Csv "C:\Reports\MailboxCreationDates.csv" -NoTypeInformation -Encoding UTF8

Piping through Get-MailboxStatistics per mailbox is slower than a single bulk query, but it’s necessary here since WhenMailboxCreated only lives on the statistics object, not the mailbox object returned by Get-Mailbox directly.

Exchange Online

Connect-ExchangeOnline -UserPrincipalName [email protected]

Get-EXOMailboxStatistics -Identity "[email protected]" | Select-Object DisplayName, WhenMailboxCreated

# organization-wide:
Get-EXOMailbox -ResultSize Unlimited | ForEach-Object {
    Get-EXOMailboxStatistics -Identity $_.Identity | Select-Object DisplayName, WhenMailboxCreated
} | Export-Csv "MailboxCreationDates.csv" -NoTypeInformation -Encoding UTF8

Same logic as on-premises, using the current ExchangeOnlineManagement module’s optimized EXO-prefixed cmdlets rather than the older, slower unprefixed ones.

Frequently asked questions

Why is WhenMailboxCreated sometimes more recent than I expect for a mailbox that’s been in use for years?
This is the clearest sign a mailbox was migrated, since a migration (cross-database, cross-forest, or to Exchange Online) creates a new mailbox record with a fresh creation timestamp even though the user experience continues uninterrupted. If you need the account’s actual tenure, use the user/AD object’s WhenCreated instead, understanding that it answers a different question.

Is there a faster way to run this across thousands of mailboxes without a per-mailbox loop?
Not through the statistics cmdlet itself, since WhenMailboxCreated is only exposed there. For very large environments, running the loop as a scheduled, off-hours job and caching the results is the practical approach, rather than trying to avoid the per-mailbox call entirely.