Get Exchange Mailbox Primary Email Addresses with PowerShell
The Challenge
I needed to create a list of all Primary SMTP addresses for all users on a client’s Exchange Online tenant, to compare with addresses registered in their email filtering system and remove invalid accounts.
Get-Mailbox and Get-Recipient both return an EmailAddresses property for each object, but they are a serialised
combination of all types of address registered against every mailbox returned.
I wanted to simply return the Primary SMTP address (which is denoted by the capitalised “SMTP:” before the address.)
How I Did It
First I wanted to see how I could manipulate the EmailAddresses Property contents and filter out exactly what I
needed, so first, in order to save time querying the tenant over and over I grabbed the Get-Mailbox results into
a variable.
$mailboxes = Get-Mailbox
I quickly realised that I only wanted to work on a single object, so I re-ran the above but selected just the first 1.
$mailboxes = Get-Mailbox | Select-Object -First 1
I took a peek at the EmailAddresses property and got what I was hoping for (edited for privacy):
$mailboxes.EmailAddresses
smtp:email.address@tenant.onmicrosoft.com
SMTP:email.address@ourdomain.com
X500:/o=First Organization/ou=OUName (RANDOMSTRING)/cn=Recipients/cn=RANDOMSTRING
x500:/o=First Organization/ou=OUName (RANDOMSTRING)/cn=Recipients/cn=RANDOMSTRING
I then ran the object through a couple of Where-Object cmdlets to see how I could isolate the SMTP: address:
$emailaddresses = $mailboxes.emailaddress | Where-Object { $_ -like ‘*SMTP*’ }
smtp:email.address@tenant.onmicrosoft.com
SMTP:email.address@ourdomain.com
Close, but too many results… Because I didn’t consider casing! Solved by simply adding a “c” to the beginning of the
comparison operator (-like becomes -clike)…
$emailaddresses = $mailboxes.emailaddress | Where-Object { $_ -clike ‘*SMTP*’ }
SMTP:email.address@ourdomain.com
Suitably pleased with the result, I then needed to expand this operation to run against all the objects returned
from Get-Mailbox - which meant getting my hands dirty in VSCode… Yay!
Building the Function
This started out innocently enough as a simple script, but as you’ll see, it began to evolve into a handy function as I saw potential applications for it with other clients.
I needed to return an object containing just the user name and the primary SMTP address, so I employed a couple of
foreach loops:
foreach ($mailbox in $mailboxes) {
$emailaddresses = $mailbox.EmailAddresses
foreach ($emailaddress in $emailaddresses) {
$smtpaddress = $emailaddress | Where-Object { $_ -clike '*SMTP*' }
[PSCustomObject]@{
'Name' = $mailbox.Name
'SMTPAddress' = $smtpaddress
}
} #foreach emailaddress
} #foreach recipient
This returned a list of 400+ objects exactly as desired (edited for privacy and brevity):
Name SMTPAddress
---- -----------
User.1 SMTP:user.1@domain.com
User.2 SMTP:user.2@domain.com
User.3 SMTP:user.3@domain.com
User.4 SMTP:user.4@domain.com
User.5 SMTP:user.5@domain.com
etc
At this point, it seemed logical to upscale this into a function - so I created the appropriate structure, added a
try/catch to deal with the possibility that the user has not connected to Exchange Online / Exchange on-premise,
then added an if/else construct to filter out the inevitable blank results due to the nested
foreach/where-object process.
The results are in my GitHub repo. The module is now a working work-in-progress and my intentions are noted in the Projects section.
Please feel free to comment and make suggestions - there’s almost certainly something I can do to refine this and I’m always keen to get tips. I’d also love to hear if this has helped anyone in their early steps into scripting and automation with PowerShell :)