Home > Exchange Server, Office365 > Exchange Proxy Address (alias) Report

Exchange Proxy Address (alias) Report

###

UPDATE (June 1 2012): This script now runs faster and puts the “Primary” SMTP address first.  For example:

Updated Output

###

Exchange Server stores user’s alternate email addresses as a multi-valued attribute within Active Directory.  For example, if my colleague Jorge has jdiaz@demolab.local as well as diazj@demolab.local, his proxyAddresses attribute would look like this:

ADUC - ProxyAddresses

Notice, the capital SMTP vs. the lowercase smtp.  There can be only one uppercase SMTP, and this represents the primary, or “reply to” address.

While, it’s very easy to view someone’s proxy addresses (often called aliases, but don’t confuse it with the “alias” attribute) within the Exchange Management Console, it can be tough to work with in the Exchange Management Shell (PowerShell) due to the data being stored as a  “Multi-Valued” attribute.  The usual “Get-Mailbox” output not only shows all addresses as a single item, but in the case “mcrowley” below, we can see the shell truncates:

get-mailbox mcrowley | select emailaddresses

While there are ways (example1, example2) to manipulate this output on the screen, I recently needed to create a complete list of all users possessing one or more secondary email address, and document what those addresses were.

On the surface, this sounds simple.  We want a list of users who have more than 1 proxy address.  At first, I thought of something like this:

Get-Mailbox -Filter {emailaddresses -gt 1} | Select EmailAddresses

Get-Mailbox -Filter {emailaddresses -gt 1} | Select EmailAddresses

But we can see this doesn’t actually capture the correct users.  In the above example, LiveUser1 only has a single proxy address, but it was returned anyway.  This is because the result is actually converted to a number, and the “-gt” or “greater than” operation is done on this number; not what we want.

To get the user collection you want, we actually need to break-out the data within this attribute, and evaluate it in a somewhat CPU intensive process.  I have written a script that helps here, by doing the following things:

  • Grabs all mailboxes and counts the number of proxy addresses for each one.  I have filtered out X400, and other non-smtp addresses.
  • If more than one proxy is found, it puts the user and it’s proxy addresses in a “nice” CSV file called c:\TooManyProxies.csv.
  • Displays a similar output to the screen.
  • Displays the total number of users found.

Here is a sample output, shown in excel (with some bolding on the headers):

Sample TooManyProxies.csv

The guts of this script might help with this exact scenario, or really, anywhere you want to break out and evaluate multi-valued attributes.  Feel free to use it and adjust as you see fit!

Some known limitations:

  • I’m no PowerShell master, so this might not be as efficient as it could be.
  • If a user has more than 10 proxy addresses, you’ll need to adjust the script and add more rows.
  • There isn’t a lot of error checking here, but I’ve used it in 2 different environments and it ran as expected.
  • -replace "smtp:"As shown below, this script doesn’t differentiate “SMTP” from “smtp”.  The addresses are listed in order stored; not necessarily relevant to us.  If you want this information shown, remove this portion from the script:

If you ONLY want a csv of everyone’s proxy address, change “-gt 1″ to “-gt 0″

Finally, the script itself:

#ProxyAddressCount-v3.3
# by Mike Crowley http://mikecrowley.us

cls

Write-Host "Getting and evaluating users. Please wait; this could take a while..." -ForegroundColor Cyan

#Getting a list of mailboxes to work with
$UserList = Get-mailbox -Resultsize unlimited

$TooManyProxies = @()

foreach ($User in $UserList) {
#get a list of SMTP and smtp proxy addresses for each User
[array]$SmtpProxyAddresses = $User.emailaddresses | Where {$_.prefixstring -like 'smtp'} | sort IsPrimaryAddress -Descending

#This section creates a lot of errors since many users don't have 3,4,5 etc proxy addresses. Here we turn error output off.
$ErrorActionPreference = 'SilentlyContinue'

#Create a new placeholder object so that we don't store the x400/x500 proxy addresses
$UserAndSmtpObject = New-Object PSObject -Property @{
Name = $user.name
PrimarySmtpAddresses1 =$SmtpProxyAddresses[0] -replace "smtp:"
SmtpAddresses2 =$SmtpProxyAddresses[1] -replace "smtp:"
SmtpAddresses3 =$SmtpProxyAddresses[2] -replace "smtp:"
SmtpAddresses4 =$SmtpProxyAddresses[3] -replace "smtp:"
SmtpAddresses5 =$SmtpProxyAddresses[4] -replace "smtp:"
SmtpAddresses6 =$SmtpProxyAddresses[5] -replace "smtp:"
SmtpAddresses7 =$SmtpProxyAddresses[6] -replace "smtp:"
SmtpAddresses8 =$SmtpProxyAddresses[7] -replace "smtp:"
SmtpAddresses9 =$SmtpProxyAddresses[8] -replace "smtp:"
SmtpAddresses10 =$SmtpProxyAddresses[9] -replace "smtp:"
}

#Turning error reporting back on
$ErrorActionPreference = 'Continue'

#Count the number of proxy addresses for each User
$SmtpProxyAddressCount = ($SmtpProxyAddresses).count

#Add Users with more than 1 proxy address to the $TooManyProxies variable
if ($SmtpProxyAddressCount -gt 1) {
$TooManyProxies += $UserAndSmtpObject
}
}

Write-Host ""
$TooManyProxies | select name, PrimarySmtpAddresses1, SmtpAddresses2, SmtpAddresses3, SmtpAddresses4, SmtpAddresses5, SmtpAddresses6, SmtpAddresses7, SmtpAddresses8, SmtpAddresses9, SmtpAddresses10 | Export-CSV c:\TooManyProxies.csv -notype
$TooManyProxies | select name, PrimarySmtpAddresses1, SmtpAddresses2, SmtpAddresses3, SmtpAddresses4, SmtpAddresses5, SmtpAddresses6, SmtpAddresses7, SmtpAddresses8, SmtpAddresses9, SmtpAddresses10
Write-Host ""

#Display a count
Write-Host "You had" ($TooManyProxies).count "Users containing two or more proxy SMTP addresses." -ForegroundColor Cyan

Write-Host ""
Write-Host ""
Write-Host "Your result file is here 'c:\TooManyProxies.csv'" -ForegroundColor Cyan
  1. April 16, 2012 at 4:10 pm | #1

    Nice powershell work :) I added SMTP addresses and primary SMTP address attributes to my AD querying tool AD Info not long ago so for anyone that doesn’t want to use powershell you can probably get what you need out of the free edition of that (http://cjwdev.co.uk/Software/ADReportingTool/Info.html). Hope you don’t mind the plug Mike, only mentioning it because I think it might be useful for people that stumble upon this post of yours :)

    • April 16, 2012 at 4:17 pm | #2

      The more the merrier. Thanks for reading!

    • Jaz
      May 29, 2012 at 10:30 pm | #3

      Heh Mike, best script Ive seen so far!….great work. Is there any way of showing the primary SMTP as the first column or with a diifferent column header?? Thanks

  2. April 16, 2012 at 4:47 pm | #4
  3. May 1, 2012 at 6:13 pm | #5

    Here’s a one-liner that will get all SMTP addresses; 1st column is name and 2nd column is SMTP address. So each user will have one line per SMTP address.

    Get-Recipient -resultSize unlimited | select name,company -expand emailAddresses | where {$_.smtpAddress} | ft name,smtpAddress

    • May 1, 2012 at 6:20 pm | #6

      Cool, thanks! I wasn’t aware of the -expand switch. When I wrote this however, my requirement was to have each person on a single row, and only those with multiple SMTP addresses.

  4. Marcos.
    May 24, 2012 at 3:28 pm | #7

    Building on your ideas, this one will get you all SMTP addresses from all Recipient Objects and their DNs.

    $SmtpProxyAddresses = Get-Recipient -ResultSize Unlimited | select-object DistinguishedName -expand emailAddresses | where {$_.prefixstring -like ‘smtp’}
    $SmtpProxyAddresses | Select-Object DistinguishedName, SmtpAddress | Export-Csv -NoTypeInformation C:\scripts\All-RecipientSMTP.csv

  5. Jaz
    May 29, 2012 at 10:30 pm | #8

    Heh Mike, best script Ive seen so far!….great work. Is there any way of showing the primary SMTP as the first column or with a diifferent column header?? Thanks

  6. David Frohme
    August 23, 2012 at 11:37 am | #10

    I modified the script to get all the proxy addresses by changing the section building the placeholder object.

    #Create a new placeholder object so that we don’t store the x400/x500 proxy addresses
    $UserAndSmtpObject = New-Object PSObject -Property @{
    Name = $user.name }
    $i = 0
    $SmtpProxyAddresses | foreach {
    $smptaddress = $_ -replace “smtp:”
    $i += 1
    if ($i -eq 1) {
    $UserAndSmtpObject | Add-Member -MemberType NoteProperty -Name PrimarySmtpAddress -Value $smptaddress
    }
    else {
    $UserAndSmtpObject | Add-Member -MemberType NoteProperty -Name (“SmtpAddress” + $i) -Value $smptaddress
    }
    }

    Then in the output section I just remove the select.
    Write-Host “”
    $TooManyProxies | Export-CSV c:\TooManyProxies.csv -notype
    $TooManyProxies
    Write-Host “”

  7. sean
    November 30, 2012 at 2:39 pm | #11

    will this script work with exchange 2003

  8. sean
    November 30, 2012 at 7:54 pm | #13

    how do i make it work for exchange 2003 help please

  9. Ross Cohen
    January 23, 2013 at 10:41 am | #14

    Is there a way to filter via an ldap query so I can select specific OUs and attributes?

    • January 23, 2013 at 11:01 am | #15

      Right now it gets all mailboxes, but you could modify line 9 so that get-mailbox uses the -filter switch. Is this what you mean?

  1. April 18, 2012 at 9:55 am | #1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 37 other followers

%d bloggers like this: