Converting SMTP Proxy Addresses to Lowercase

May 14, 2012 4 comments

Update: Be aware, this script has not been tested with SIP, X400 or other address types. I am working on an update to validate these scenarios, but in the meantime, proceed at your own risk with these address types.

I recently encountered a question in an online forum where someone asked for a script to convert all of their user’s email addresses to lower case values.  While this doesn’t affect the message delivery, it can have an impact on aesthetics when the address is displayed in an external recipient’s email client.  An Exchange Email Address Policy can do this to some degree, but I wanted to see how it could be done with PowerShell.

The challenge with a script like this is twofold:

  1. Email addresses (proxy addresses) are a multi-valued attribute, which can be tricky to work with.
  2. PowerShell is generally not case-sensitive, and therefore when we try to rename Mr. Gallalee’s email address in the screenshot below, we can see that it does not work:

WARNING: The command completed successfully but no settings of 'demolab.local/Users/Rob Gallalee' have been modified.

After a little bit of inspiration from a script written by Michael B Smith, I came up with the below:


$MailboxList = Get-Mailbox  -ResultSize unlimited

$MailboxList | % {

$LoweredList = @()
$RenamedList = @()

foreach ($Address in $_.EmailAddresses){
if ($Address.prefixstring -eq "SMTP"){
$RenamedList += $Address.smtpaddress + "TempRename"
$LoweredList += $Address.smtpaddress.ToLower()
}
}
Set-mailbox $_ -emailaddresses $RenamedList -EmailAddressPolicyEnabled $false
Set-mailbox $_ -emailaddresses $LoweredList

#Without this line the "Reply To" Address could be lost on recipients with more than one proxy address:
Set-mailbox $_ -PrimarySmtpAddress $_.PrimarySmtpAddress
}

This script works as follows:

  1. Puts all mailboxes into the $MailboxList variable.  If you don’t want all mailboxes,  edit the Get-Mailbox cmdlet as you see fit.
  2. Filters out X400 and other non-SMTP addresses.
  3. Creates an array called $RenamedList which stores each proxy address with “TempRename” appended to it (e.g. Rgallalee@demolab.localTempRename).
  4. Creates another array ($LoweredList) and use the “ToLower” method on each proxy address.
  5. Sets the proxy address for the user to the value of $RenamedList and then to $LoweredList.
    1. This is how we get around the case case insensitivity – name it to something else and then name it back.
  6. Step 4 and 5 don’t preserve the “Primary” / “Reply-To” address, so we set it back manually with the last line.

Note: This script turns off the email address policy for each user.

As always, feedback is welcome.

100,000 and Counting…

May 1, 2012 2 comments

I am proud to report that today this blog has reached 100,000 views! Maintaining this site has been very rewarding for me, and I’m happy to have been able to contribute to the technical community, which has served me very well since I entered the infotech industry ten years ago.

WordPress.com provides statistics on how every blog is used.  Here are some facts about mine:

  • My post on setting logon wallpaper for Windows 7 has been my most popular
  • Google’s search results have sent most of my readers (by far). TechNet forums comes in 2nd
  • Google has sent people to this site at a rate 34x to that of Bing
  • Only 9 viewers have used ask.com to find me (GASP!)
  • The anti-spam feature for comments is very good, though the comment spam I receive has been surprisingly complementary; I’m half way inclined to let it through. Winking smile

Thanks to all my visitors.  Please share my site with a friend, visit the sites that pay my bills (Mike’s Links – top right), and if you have any topic suggestions or feedback in general, please contact me!

Categories: Personal Tags:

Combining PowerShell Cmdlet Results

April 17, 2012 10 comments

In my last post I used used New-Object to create an desirable output when the “Get-Mailbox” cmdlet didn’t meet my needs.  If your eyes glazed over trying to read the script, let me make it a bit simpler by focusing on a straight forward example.

Say you need to create a list of user’s mailbox size with their email address.  This sounds like a simple request, but what you’d soon find is that mailbox sizes are returned with the Get-MailboxStatistics cmdlet and the email address is not.  For that, you need to use another cmdlet, such as Get-Mailbox.

With the New-Object cmdlet, we are able to make a custom output that contains data from essentially wherever we want.

See this example:

$MyObject = New-Object PSObject -Property @{
EmailAddress = $null
MailboxSize = $null
}

In this example, I have created a new object with 2 fields, and saved it as the $MyObject variable.

For now, we’ve set the data to null, as shown below:

$MyObject

The next step is to populate each of those fields.  We can write to them one at a time with lines like this:

$MyObject.EmailAddress = (Get-Mailbox mcrowley).PrimarySmtpAddress
$MyObject.MailboxSize = (Get-MailboxStatistics mcrowley).TotalItemSize

Note: The variable we want to populate is on the left, with what we want to put in it on the right.

To confirm our results, we can simply type the variable name at the prompt:

$MyObject with data

Pretty cool, huh?

Ok, so now about that list.  My example only shows the data for mcrowley, and you probably need more than just 1 item in your report, right?

For this, you need to use the foreach loop.  You can read more about foreach here, but the actual code for our list is as follows:

(I am actually going to skip the $null attribute step here)

$UserList = Get-mailbox -Resultsize unlimited
$MasterList = @()
foreach ($User in $UserList) {
$MyObject = New-Object PSObject -Property @{
EmailAddress = (Get-Mailbox $User).PrimarySmtpAddress
MailboxSize = (Get-MailboxStatistics $User).TotalItemSize
}
$MasterList += $MyObject
}
$MasterList

$MasterList with data

Finally, if you wanted to make this run faster, we really don’t need to run “get-mailbox” twice.  For better results, replace the line:

EmailAddress = (Get-Mailbox $User).PrimarySmtpAddress

With this one:

EmailAddress = $User.PrimarySmtpAddress

Exchange Proxy Address (alias) Report

April 16, 2012 16 comments

###

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

Cloud Connections Session Slides

March 29, 2012 Leave a comment

Thanks to those who attended my sessions at this weeks Cloud Connections conference.  If you missed it, or would like to download the slides, I’ve made them available here.

 

Piloting Exchange Online

 

Forefront Online Protection for Exchange

 

If you are looking for slides from other speakers, please see here: 


http://www.devconnections.com/updates/LasVegas_Spring12/Cloud

Categories: Office365 Tags: ,

Ads are Annoying

March 20, 2012 Leave a comment

Thanks to all who read my blog!  Today I purchased the “No Ads” upgrade, and thus made the internet a cleaner place.  Hope you all enjoy.

 

Categories: Personal Tags:

Windows Server “8” Beta Hyper-V Component Architecture Poster

March 20, 2012 Leave a comment

Late last week, Microsoft released another high-quality poster.  This time for Hyper-V in Windows 8 (beta).

Hyper-V Component Architecture Poster

You can download this poster here.

If you’re interested in learning more on Hyper-V in Windows 8, click some of the links below.  This update to Hyper-V is my favorite part of Windows Server 8!

Reading

Videos

Categories: Windows Server Tags: ,
Follow

Get every new post delivered to your Inbox.

Join 37 other followers