Exchange PowerShell: How to list all SMTP email addresses in Exchange

Exchange PowerShell

In my last Exchange PowerShell post i looked at listing users hidden from the Global Address List. In this post we’ll look at listing all email addresses in use in Microsoft Exchange. This can be useful if you are trying to add an email address and you get an error message because it is already in use somewhere.

Although email addresses are most often associated with mailboxes, they can be found in other items too. In Exchange, Contacts and Distribution lists also have email addresses (as do Public Folders which we’ll look at another time). For that reason we can’t use Get-Mailbox which we used in the last post as that will limit our search to mailboxes only, instead we’ll be using Get-Recipient.

If you pipe Get-Recipient into Get-Member you will see an EmailAddresses property which is exactly what we are after. As you can see below GM is an alias of Get-Member.

The command is:

Get-Recipient | GM

Get-Recipient Get-Member

Based on what we learnt in the last post we can start off with the command:

Get-Recipient | Select Name, EmailAddresses

In the image below I have compared the output of Get-Recipient with Get-Mailbox so that you can see Get-Recipient is returning more information.

Comparison between get-mailbox and get-recipient

You’ll also note that some of the mailboxes appear to have more than one email address, now how will we expand the property to see them all?

The Select command is very powerful to find out more about it run the command:

Get-Help Select -Full

If you run the command above you will see one of the parameters is -ExpandProperty, which we will use to expand the EmailAddresses property.

The command is:
Get-Recipient | Select Name -ExpandProperty EmailAddresses

get-recipient select name expand emailaddressesAs you can see, where a user has two email addresses they are listed twice. I’d like to further refine the output and just Select the Name and the SmtpAddress. So the command looks like this:

Get-Recipient | Select Name -ExpandProperty EmailAddresses | Select Name,  SmtpAddress

Get-Recipient Select Name ExpandProperty EmailAddresses Select Name SmtpAddressNow that looks like the perfect format to export to csv.

So our final command looks like this:

Get-Recipient | Select Name -ExpandProperty EmailAddresses | Select Name, SmtpAddress | Export-csv c:\temp\AllEmailAddress.csv

The PowerShell command above works on both Exchange 2007 and Exchange 2010.

Related Posts:

1. Office365 PowerShell: How to the find out mailbox sizes in Office365 (and Exchange 2016) using PowerShell

2. How to install Exchange 2013 (SP1) on Windows Server 2012 R2

3. Exchange 2013 Initial Configuration Settings multi-part series

4. Exchange PowerShell: How to check the number of items in the Inbox, Sent Items, Deleted Items and Junk Email

5. Office 365 PowerShell: How to bulk change Office 365 calendar permissions using Windows PowerShell

16 thoughts on “Exchange PowerShell: How to list all SMTP email addresses in Exchange

  1. Willis

    I looked high and low for this. Thank you for posting. My final command was this:
    Get-Recipient | select name, samaccountname, primarysmtpaddress | export-csv c:YourFile.csv

  2. Micro Four Thirds

    Nice! For testing I used -resultsize 10 and piped to screen with | ft -autosize -wrap instead of export

    Spreadsheet with every smtp address listed. My final command was this:
    Get-Recipient -RecipientType usermailbox -SortBy LastName -resultsize Unlimited | Select Name, DisplayName, FirstName, LastName, samaccountname, primarysmtpaddress -ExpandProperty EmailAddresses | select Name,DisplayName, FirstName, LastName,samaccountname,smtpaddress | Export-Csv -force -notype c:tempCompany-Recipient-usermailbox-ALL-smtp-121814.csv

    Thanks Carl.

  3. Tomasz

    Get-Mailbox -ResultSize Unlimited -OrganizationalUnit “OU=XXXXXXXUsers,OU=XXXXXXX,DC=XXXXXXX,DC=XXX” |Select-Object DisplayName,PrimarySmtpAddress, @{Name=“EmailAddresses”;Expression={$_.EmailAddresses |Where-Object {$_.PrefixString -ceq “smtp”} | ForEach-Object {$_.SmtpAddress}}} | Export-CSV c:exportsmtp.csv

  4. Erik


    Will this run in Exchange 2013? When I try to run this command:

    Get-Recipient “Usernname”| Select Name -ExpandProperty EmailAddresses | Select Name, SmtpAddress | Export-csv c:AllEmailAddress.csv

    …the .csv has the Name, but nothing for SmptAddress.

    When I run this command:

    Get-mailbox “Username”| Select Name -expandproperty EmailAddresses

    …the output lists each address on a separate line like I want, but it is not paired with Name.

    Thank you!

      1. Stefan Åberg

        Get-Recipient -ResultSize Unlimited | Where-Object {$_.RecipientType -eq “UserMailbox”} | Select-Object name, RecipientType, PrimarySMTPAddress

        a list of all users and their email addresses.
        Office 365 – checked to work!

  5. Simon Elbaz

    I have read your posts in order to find a tip on how to:
    – extract the people view for each user
    – each user calendar.

    Could you please give me a hint ?

    Simon Elbaz

    1. Post author

      Hi Simon, I’m not sure exactly what you are asking? Are you looking for the permissions set on the calendar?

      1. Simon Elbaz

        Hi Carl,

        Thanks for your answer.

        For the moment, I just want to focus on the Outlook 2013 People view extraction.
        I am looking for a way to extract the People view of each mailbox (name, surname, email, companyname …. of each contact) in order to convert them to VCF format.
        The Get-MailContact cmlet extracts the contacts created with the ECP interface not by the MailBox user.

        Simon Elbaz

  6. Bill Curtis

    I use Exchange in Office 365. I needed a list of the user, primary SMTP address, and other SMTP addresses, but I could not get smtpaddress to give any results.

    I decided to make a function for this. I am sure there are easier ways, but here is what I came up with.

    Start of Code
    function Get-EmailAddresses
    [Parameter(Mandatory = $true,
    ValueFromPipeline = $true,
    Position = 1)]

    #TODO: Place script here
    # Write-Output $Name
    # get-recipient $Name | select name, primarysmtpaddress, @{ name = “EAddresses”; Expression = { -expandproperty $_.emailaddresses } }
    # get-recipient $Name | select name -expandproperty emailaddresses | where { $_ -like “smtp:*” }
    $Array = @()
    foreach ($user in $alias)
    $USR = (get-recipient $user | select firstname, lastname, primarysmtpaddress)
    $PSMTP = $USR.primarysmtpaddress
    $EMA = get-recipient $user | select -expandproperty emailaddresses | where { $_ -like “smtp:*” -and $_ -ne “smtp:$PSMTP” -and $_ -notlike “*onmicrosoft*” }
    $obj = New-Object PSObject
    $obj | Add-Member -MemberType NoteProperty -Name “FirstName” -Value $USR.FirstName
    $obj | Add-Member -MemberType NoteProperty -Name “LastName” -Value $USR.LastName
    $obj | Add-Member -MemberType NoteProperty -Name “PrimarySMTPAddress” -Value $PSMTP
    foreach ($Emaddr in $EMA)
    $EML = $Emaddr -split “:”,2
    $obj | Add-Member -MemberType NoteProperty -Name “EmailAddress” -Value $EML[1]
    $array += $obj
    $obj = New-Object PSObject

    Write-Output $array
    End of Code

  7. Alex

    This works fine if you’re ON the Exchange server. What if you want to do this from a different/remote machine?

  8. David

    Please post the full script from start to finish here for those of us that pretty much know what PowerShell is and that is the scope of our knowledge. The statement below suggests that all that is necessary is this single statement. Yet when I run it, it fails with ‘The term Get-Recipient is not recognized…”

    “So our final command looks like this:
    Get-Recipient | Select Name -ExpandProperty EmailAddresses | Select Name, SmtpAddress | Export-csv c:\temp\AllEmailAddress.csv”

    1. Eduardo

      Same here….”The term Get-Recipient is not recognized…”

      The term ‘Get-Recipient’ 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 and try again.

Comments are closed.