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.
Thank you, This helped med copy Proxyaddresses from AD account to another. along with several other Attributes in Active Directory.
You’re welcome and I’m glad it helped!