PowerShell: Moving SMTP Proxy Addresses to a New Mailbox

I do a lot of work with Exchange and Exchange Online (Office 365).  A common task is to move proxy SMTP addresses from one mailbox to another.  And commonly run tasks must get scripted.

It’s an obscure English by-law.

More detail below.

So the important things this script needs to do are;

  • Moving SMTP addresses from one mailbox to another.
  • As an Exchange mailbox can’t exist without an SMTP address, the script will need to replace the moved SMTP addresses with a dummy address.
  • Another problem to solve is that you can’t remove an SMTP proxy address if it’s the default SMTP reply address;  a new address needs to be set as default first.
  • Mailboxes often have multiple, non-SMTP proxy addresses and I don’t want the script to affect those if possible.

The full script is below and a breakdown of how it works follows;

set-strictmode -version Latest
<# .SYNOPSIS Moves all the proxy addresses from one mailbox to another. .DESCRIPTION Moves all the proxy SMTP addresses from one mailbox to another. All the proxy addresses on the source are replaced by a single, dummy SMTP address. Returns true if the function completes. .PARAMETER SourceMailbox Must be passed as an SMTP address. Must contain the PrimarySMTP address of the mailbox to move SMTP addresses from. .PARAMETER TargetMailbox Must be passed as an SMTP address. Must contain at least the PrimarySMTP address of the mailbox to copy the proxy addresses to. .EXAMPLE Move-SharedProxyAddresses -SourceMailbox Role2@contoso.com -TargetMailbox alanb@contoso.com -Verbose .NOTES Name : Move-SharedProxyAddresses Author : HerringsFishBait.com V1.0 Initial Version #>
function Move-SharedProxyAddresses
{
    param
    (
        [Parameter(Mandatory=$true)]
        [String]$SourceMailbox,
        [Parameter(Mandatory=$true)]
        [String]$TargetMailbox
    )
    [string]$DummyEmailAddressDomain="@dummy.local"
    Write-Verbose "Moving Proxy Addresses."
    Write-Verbose "Source Mailbox : $SourceMailbox"
    Write-Verbose "Target Mailbox : $TargetMailbox"
    $SourceMailboxObject=Get-Mailbox $SourceMailbox
    if ($SourceMailboxObject -eq $Null)
    {
        Write-Verbose "Unable to find source mailbox." 
        Return $False
    }
    if ($SourceMailboxObject -is [array])
    {
        Write-Verbose "More than one source mailbox found." 
        Return $False        
    }
    $TargetMailboxObject=Get-Mailbox $TargetMailbox
    if ($TargetMailboxObject -eq $Null)
    {
        Write-Verbose "Unable to find target mailbox." 
        Return $False
    }
    if ($TargetMailboxObject -is [array])
    {
        Write-Verbose "More than one target mailbox found." 
        Return $False        
    }
    $ProxyAddresses= $SourceMailboxObject.EmailAddresses | Where-Object {$_.PrefixString -eq "SMTP"} | 
        Select-Object -ExpandProperty AddressString  
    $DummyEmailAddress=$SourceMailboxObject.PrimarySMTPAddress.Local+$DummyEmailAddressDomain
    Write-Verbose "Replacing Source SMTP addresses with dummy SMTP address: $DummyEmailAddress"
    $OldAddressStrings=@()
    Foreach ($ExistingProxyAddress in $SourceMailBoxObject.EmailAddresses)
    {
        if ($ExistingProxyAddress.Prefix.DisplayName -ne "SMTP")
        {
            $OldAddressStrings+=$ExistingProxyAddress.ProxyAddressString
        }
    }
    $OldAddressStrings+="SMTP:$DummyEmailAddress"
    $SourceMailboxObject | Set-Mailbox -EmailAddresses $OldAddressStrings -EmailAddressPolicy:$False
    Write-Verbose "Copying Source proxy addresses to target"
    Foreach ($ProxyAddress in $ProxyAddresses)
    {
        Write-Verbose "Adding $ProxyAddress"
        $TargetMailboxObject | Set-Mailbox -EmailAddresses @{add=$ProxyAddress} -EmailAddressPolicy $False
    }
    Return $True
}

The initial parts of the script take the source and target mailboxes (via their primary SMTP addresses) and then sanity checks them;  it confirms that querying for each address returns a single mailbox.

A dummy SMTP domain (“@dummy.local“) is defined at the start.  The script will use this to create the new SMTP address that will replace all the old ones on the source mailbox.

$ProxyAddresses= $SourceMailboxObject.EmailAddresses | Where-Object {$_.PrefixString -eq "SMTP"} | 
        Select-Object -ExpandProperty AddressString  
    $DummyEmailAddress=$SourceMailboxObject.PrimarySMTPAddress.Local+$DummyEmailAddressDomain

The first command gets a list of all the SMTP proxy addresses on the source mailbox.  These get expanded into an array.

Then a new dummy SMTP address gets generated from the existing local part of the primary SMTP address (the bit before the “@”) with the dummy domain added to the end.

    $OldAddressStrings=@()
    Foreach ($ExistingProxyAddress in $SourceMailBoxObject.EmailAddresses)
    {
        if ($ExistingProxyAddress.Prefix.DisplayName -ne "SMTP")
        {
            $OldAddressStrings+=$ExistingProxyAddress.ProxyAddressString
        }
    }
    $OldAddressStrings+="SMTP:$DummyEmailAddress"
    $SourceMailboxObject | Set-Mailbox -EmailAddresses $OldAddressStrings -EmailAddressPolicy:$False

Here the script builds a list of proxy addresses on the source mailbox that aren’t SMTP addresses.  The new, dummy SMTP address is added to that list as the default address (it has SMTP: in capitals as a prefix).

This gets around the problem where its not possible to remove an SMTP address if it’s the default without setting a new as the default first;  the script just replaces the entire list on the source in one go.

Note that the script also sets the addresses NOT to use email address policy;  I didn’t want the policy to overwrite the changes I’ve made.

    Foreach ($ProxyAddress in $ProxyAddresses)
    {
        Write-Verbose "Adding $ProxyAddress"
        $TargetMailboxObject | Set-Mailbox -EmailAddresses @{add=$ProxyAddress} -EmailAddressPolicy $False
    }
    Return $True

Finally all the source SMTP addresses are added to the target mailbox.

If the script got this far we’re assuming it finished so it returns $True to show it was successful;  if I revisit this I may add some sanity-checking / error-catching here to make sure.

2 thoughts on “PowerShell: Moving SMTP Proxy Addresses to a New Mailbox”

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 )

Google+ photo

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

Connecting to %s