Removing Old Emailaddresses/ProxyAddresses in Exchange 2007

I have a client who has multiple business units. Each business unit is placed into its own Organizational Unit (OU) in Active Directory and the business unit has its own unique Email Address Policy (EAP) that (using a RecipientFilter) assigns specific email addresses to all users in that OU.

The client has changed the name of one of their business units, and as of today, the old email addresses were to “go away”.

There is no in-built functionality for automatically removing email addresses. You can modify the EAP to specify a new address template as the default, but even when you remove the old address template, that email address is not removed from the user object (Exchange has worked this way since at least Exchange 2000, Exchange 5.5 used a somewhat different model).

What do you do? Well, you use PowerShell of course! This “one-liner” does the job:

get-mailbox -organizationalunit ad.example.com/BusinessUnitOU/users |% { $a = $_.emailaddresses; $b = $_.emailaddresses; foreach($e in $a) { if ($e.tostring() -match "old-email-domain") { $b -= $e; } } ; $_ | set-mailbox -emailaddresses $b }

You can enter this as a single line (and I did). However, the command is easier to understand when you separate it out, as shown below:

get-mailbox -organizationalunit ad.example.com/BusinessUnitOU/users |% 
    { 
        $a = $_.emailaddresses; 
        $b = $_.emailaddresses; 
        foreach ($e in $a) 
        { 
            if ($e.tostring() -match "old-email-domain") 
            { 
                $b -= $e; 
            } 
         }

         $_ | set-mailbox -emailaddresses $b 
    }


The Get-Mailbox command specifies the unique organizational unit that we are looking at. In this case, Get-Mailbox will return a mailbox object for all mailboxes that exist within the ad.example.com/BusinessUnitOU/users organizational unit. Note that I have not used the distinguishedName format for the organizational unit, but instead the X.500 format. Either is acceptable. However, the X.500 format only requires quoting when you have spaces in your organizational unit names. The distinguishedName format must always be quoted or escaped due to its use of commas (and how PowerShell interprets commas in open text strings).

The “|%” syntax indicates that the output of the Get-Mailbox command is to be evaluated, for each object returned, based on the following script block. In this case, the script block begins on the next line with “{” in column 4 and terminates 12 lines later with a “}” in column 4.

First, we make two copies of the email address collection for the mailbox that is returned. Note that setting “$b = $a” would have a different behavior! Instead of creating a copy of the collection, it would create a reference – that is, $b would point to the same collection as $a, and the following loop would not work properly, as described in the next paragraph.

Next, we evaluate each email address contained within the email address collection ($a). If a particular email address matches the old email address domain, we remove that particular email address from the second collection ($b). If we removed it from the original collection ($a), then the foreach loop would fail. Not a good thing to have happen – which is why we have two collections!

After examining all of the email addresses in the collection, we pipe the mailbox object to Set-Mailbox using the new/adjusted collection. And we are done!

But you don’t need to understand the script in order to use the script. To use the script, replace the -organizationalunit parameter with the one you are wanting to change (or completely remove the parameter if you want to affect all mailboxes). Next, replace old-email-domain with the domain you are want to remove. That’s all it takes.

Until next time…

If there are things you would like to see written about, please let me know!

[Edit March 29, 2012]

Mike Crowley, another Exchange MVP, makes the following comment that I thought I would share:

Michael, this was very helpful, thanks again! I
needed to do this for one of my customers, however the address that needed to
‘go away’ was a parent domain of one that needed to stay (e.g. ‘domain.com’
needed to go away, but ‘subdomain.domain.com’ needed to stay). I modified
your script and ran the below:

get-mailbox -organizationalunit
ad.domain.com/BusinessUnitOU/users | % { $a = $_.emailaddresses; $b =
$_.emailaddresses; foreach($e in $a) { if (($e.tostring() -match
“domain.com”) -and ($e.tostring() -notmatch
“subdomain.domain.com”)) { $b -= $e; } } ; $_ | set-mailbox
-emailaddresses $b }

-Mike


Follow me on twitter: @EssentialExch

Leave a Reply

Your email address will not be published. Required fields are marked *