How to Export Every SMTP Address for All Mailboxes with PowerShell
Every mailbox in Exchange, on-premises or Exchange Online, can carry multiple SMTP addresses (a primary address plus any number of secondary aliases), and pulling a clean list of all of them across every mailbox is one of the most common reporting tasks in a real environment: migrations, domain renames, and compliance reviews all need this at some point. Here is the current, correct way to do it, on-premises and in Exchange Online.
Understanding what you’re actually looking at
Each mailbox’s EmailAddresses property holds every SMTP address assigned to it, prefixed to show which is primary. A capital SMTP: prefix marks the primary (reply-from) address, and a lowercase smtp: prefix marks a secondary alias. Getting this distinction right matters for any report you hand off, since mixing them up misrepresents which address a user actually sends from.
On-premises Exchange Server
Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName, PrimarySmtpAddress,
@{Name="AllSmtpAddresses";Expression={($_.EmailAddresses | Where-Object {$_ -like "smtp:*" -or $_ -like "SMTP:*"}) -join "; "}} |
Export-Csv "C:\Reports\AllSmtpAddresses.csv" -NoTypeInformation -Encoding UTF8
PrimarySmtpAddress is a dedicated property that always gives you the correct primary address directly, faster than parsing it back out of EmailAddresses yourself. The custom expression above captures every address, primary and secondary, in one column for the full picture.
Exchange Online
Use the current ExchangeOnlineManagement module (version 3.x), the REST-based module that replaced the older remote PowerShell session approach. If you haven’t already:
Install-Module -Name ExchangeOnlineManagement -Scope CurrentUser
Connect-ExchangeOnline -UserPrincipalName [email protected]
Then the report itself:
Get-EXOMailbox -ResultSize Unlimited -Properties EmailAddresses |
Select-Object DisplayName, PrimarySmtpAddress,
@{Name="AllSmtpAddresses";Expression={($_.EmailAddresses | Where-Object {$_ -like "smtp:*" -or $_ -like "SMTP:*"}) -join "; "}} |
Export-Csv "AllSmtpAddresses.csv" -NoTypeInformation -Encoding UTF8
Get-EXOMailbox, not the older Get-Mailbox, is the optimized cmdlet for Exchange Online specifically. It only returns the properties you explicitly request via -Properties, which is significantly faster across a large tenant than the older cmdlet pulling every property by default.
Filtering to just secondary aliases (a common follow-up request)
Get-EXOMailbox -ResultSize Unlimited -Properties EmailAddresses |
Select-Object DisplayName, @{Name="Aliases";Expression={($_.EmailAddresses | Where-Object {$_ -clike "smtp:*"}) -join "; "}}
Note the -clike (case-sensitive like) rather than plain -like here, since smtp: lowercase specifically means “secondary,” and a case-insensitive match would also catch the primary address.
Frequently asked questions
Why does the same mailbox sometimes show more addresses than I expect, including ones on a domain I don’t recognize?
The most common cause is an accepted domain used for a legacy migration or a third-party mail relay that was never cleaned up. Cross-reference unfamiliar domains against Get-AcceptedDomain (on-premises) or Get-AcceptedDomain in Exchange Online to confirm whether the domain is even still authoritative for your organization.
Can I run this against a single mailbox instead of the whole organization?
Yes, replace -ResultSize Unlimited with -Identity "[email protected]" on either cmdlet. This is the faster option when you’re troubleshooting one specific mailbox’s address configuration rather than running a full organization-wide report.
