Removing Proxy Addresses from Exchange Recipients


I saw a request come through the other day for a method to remove unwanted proxy addresses for contacts.  I'd had some code sitting around from a project a few years back and decided to freshen it up, and maybe add some newer tricks.

So, the original idea was to select a bunch of users (Get-MailUser, Get-MailContact, etc) and then remove proxy addresses matching patterns.  And this works splendidly:

[array]$contacts = Get-MailContact -Resultsize Unlimited
ForEach($contact in $contacts)
{
Write-Host Processing $contact
For($i=($contact.EmailAddresses.count)-1; $i -ge 0; $i--)
{
$address=$contact.EmailAddresses[$i]
$addressString=$address.addressString.ToString()
If($addressString -like "*contoso.com*")
{
Write-Host -ForegroundColor Green Removing $addressString
$contact.EmailAddresses.removeat($i)
}
}
$contact|Set-MailContact -EmailAddresses $contact.EmailAddresses
}

But, what if there are a lot of address patterns that I want to remove?

We can just add an array of patterns to remove and a nested loop like this:

[array]$StringsToRemove = ('tailspintoys.ca','nwtraders.net','fabrikam.com')
[array]$contacts = Get-MailContact -Resultsize Unlimited

ForEach($contact in $contacts)
{
Write-Host Processing $contact
For($i=($contact.EmailAddresses.count)-1; $i -ge 0; $i--)
{
Foreach ($string in $StringsToRemove)
{
$address=$contact.EmailAddresses[$i]
$addressString=$address.addressString.ToString()
If($addressString -like "*$string*")
{
Write-Host -ForegroundColor Green "Removing $addressString"
$contact.EmailAddresses.removeat($i)
}
}
$contact | Set-MailContact -EmailAddresses $contact.EmailAddresses
}
}

But, Aaron, what if I want to do more than just contacts?  What if I want to remove the proxies from MailUsers, Mailboxes, AND/OR contacts?

Now we're talking about a script.

PARAM(
[ValidateSet('UserMailbox','MailUser','MailContact')]
[array]$RecipientTypes = ('UserMailbox','MailUser','MailContact'),
[ValidatePattern("^([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9]|Unlimited)$")]
[string]$ResultSize = "Unlimited",
[string]$Identity,
[array]$StringsToRemove
)

Foreach ($Type in $RecipientTypes)
{
Switch ($Type)
{
UserMailbox
{
if ($Identity)
{ $mailboxes = Get-Mailbox -Identity $Identity -wa SilentlyContinue -ea SilentlyContinue }
else
{ $mailboxes = Get-Mailbox -Resultsize $Resultsize -wa SilentlyContinue -ea Silently Continue 
Write-Host "Procesing $($Resultsize) UserMailbox objects."}
ForEach($mailbox in $mailboxes)
{
Write-Host Processing $mailbox
For($i=($mailbox.EmailAddresses.count)-1; $i -ge 0; $i--)
{
Foreach ($string in $StringsToRemove)
{
$address=$mailbox.EmailAddresses[$i]
$addressString=$address.addressString.ToString()
If($addressString -like "*$string*")
{
Write-Host -ForegroundColor Green "Removing $addressString"
$mailbox.EmailAddresses.removeat($i)
}
}
$mailbox | Set-Mailmailbox -EmailAddresses $mailbox.EmailAddresses
}
}
} # End UserMailbox
MailUser
{
If ($Identity)
{ $mailusers = Get-MailUser -Identity $Identity -wa SilentlyContinue -ea SilentlyContinue }
else
{ $mailusers = Get-MailUser -Resultsize $Resultsize -wa SilentlyContinue -ea SilentlyContinue 
Write-Host "Processing $($Resultsize) MailUser objects."}
ForEach($mailuser in $mailusers)
{
Write-Host Processing $mailuser
For($i=($mailuser.EmailAddresses.count)-1; $i -ge 0; $i--)
{
Foreach ($string in $StringsToRemove)
{
$address=$mailuser.EmailAddresses[$i]
$addressString=$address.addressString.ToString()
If($addressString -like "*$string*")
{
Write-Host -ForegroundColor Green "Removing $addressString"
$mailuser.EmailAddresses.removeat($i)
}
}
$mailuser | Set-Mailmailuser -EmailAddresses $mailuser.EmailAddresses
}
}
} # End MailUser
MailContact
{
If ($Identity)
{ $contacts = Get-MailContact -Identity $Identity -wa SilentlyContinue -ea SilentlyContinue }
else
{ $contacts = Get-MailContact -Resultsize $Resultsize -wa SilentlyContinue -ea SilentlyContinue
Write-Host "Processing $($Resultsize) MailContact objects." }
ForEach($contact in $contacts)
{
Write-Host Processing $contact
For($i=($contact.EmailAddresses.count)-1; $i -ge 0; $i--)
{
Foreach ($string in $StringsToRemove)
{
$address=$contact.EmailAddresses[$i]
$addressString=$address.addressString.ToString()
If($addressString -like "*$string*")
{
Write-Host -ForegroundColor Green "Removing $addressString"
$contact.EmailAddresses.removeat($i)
}
}
$contact | Set-MailContact -EmailAddresses $contact.EmailAddresses
}
}
} # End MailContact
} # End Switch
} # End Foreach $Type

Be fruitful and multip--er, remove!

You can get the completed script at https://gallery.technet.microsoft.com/Remove-Exchange-Proxy-eb5be217.

Comments (8)

  1. turbomcp says:

    Great stuff as usual
    Thanks

  2. Carmen says:

    Everything is very open and very clear explanation of issues. was truly information. Your website is very useful. Thanks for sharing.
    voyance – http://carmen-voyance.com/

  3. turbomcp says:

    Forgot to say that’s first time I noticed you could count backwards with .-1 and i–
    Always learn something new here:)
    Thanks again

    1. Oh, yes–just like other languages, ++ and — increment/decrement by one.

  4. Randy says:

    I’m having issues getting this script to work. For some reason, when the script uses $addressString = $address.addressString to get the string value, it shows up blank for me. If I use $addressString = $address.toString() it does work. Am I missing something?

    Thanks – Randy

    1. Ah, yes. Depending on what version of Exchange and PoweShell you are using, it might require that (otherwise, it shows it as component parts). I’ll update it accordingly. Thanks!

  5. joko says:

    Thanks for this! – Are you able to add a log file, just so it outputs the processed/removed addresses into a csv?

    1. Yes, you could do something like “Add-Content $address -Path output.txt” above each removeat($i) line.

Skip to main content