Exchange Proxy Address (alias) Report
###
UPDATE (June 1 2012): This script now runs faster and puts the “Primary” SMTP address first. For example:
###
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:
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:
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
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):
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.
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


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
The more the merrier. Thanks for reading!
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
If you like this script, please vote on it here:
http://gallery.technet.microsoft.com/scriptcenter/Exchange-Proxy-Address-98d05872
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
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.
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
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
Jaz, I’ve made the update. Please see above.
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 “”
will this script work with exchange 2003
Not as is, no.
how do i make it work for exchange 2003 help please
Is there a way to filter via an ldap query so I can select specific OUs and attributes?
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?