This script and the accompanying post have been updated.
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('Mailbox', 'MailUser', 'MailContact')] [array]$RecipientTypes = @('Mailbox', '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) { Mailbox { if ($Identity) { [array]$mailboxes = Get-Mailbox -Identity $Identity -wa SilentlyContinue -ea SilentlyContinue } else { [array]$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 If ($addressString -like "*$string*") { Write-Host -ForegroundColor Green "Removing $addressString" $mailbox.EmailAddresses.removeat($i) } } $mailbox | Set-Mailbox -EmailAddresses $mailbox.EmailAddresses } } } # End Mailbox MailUser { If ($Identity) { [array]$mailusers = Get-MailUser -Identity $Identity -wa SilentlyContinue -ea SilentlyContinue } else { [array]$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 If ($addressString -like "*$string*") { Write-Host -ForegroundColor Green "Removing $addressString" $mailuser.EmailAddresses.removeat($i) } } $mailuser | Set-Mailuser -EmailAddresses $mailuser.EmailAddresses } } } # End MailUser MailContact { If ($Identity) { [array]$contacts = Get-MailContact -Identity $Identity -wa SilentlyContinue -ea SilentlyContinue } else { [array]$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 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.
Hi Aaron
Anyway you can update this script to include remote mailboxes for mailboxes that have already been migrated to O365
It’s updated. Give it a try.
Hi Aaron
Thank you very much. It shows as processing and updated the log file but does not actually remove the CCMAIL address so I am not sure if I am possibly doing something wrong?
I also tried it with an smtp address, same thing.
I tried this on both a remote mailboa as well as a mailbox still on-prem, same result.
Not sure if this has anything to do with the version of exchange? We are running 2016 CU 10
Hi,
I am not clear how to use this script, do I just run the ps1 and am prompted for the parameters? I have tried to add the parameters to the PARAM( section in the script and tried running the parameters with the run string e.g. ./RemoveExchangeProxyAddresses.ps1 -identity username -stringstoremove stringtoremove but both come back with ” Parameter attributes need to be a constant or a script block.”. Just a bit wary as I am testing this on a production system (I dont have a test box running exchange at the moment).
Thanks in advance and sorry for the newbie question.
I’ve updated the script and examples.
Here’s the examples I posted inside the help file:
.EXAMPLE
.\Remove-ExchangeProxyAddresses.ps1 -Identity adelev@contoso.com -StringsToRemove “@fabrikam.com”
Removes string ‘@fabrikam.com’ inside of proxy address array for adelev@contoso.com.
.EXAMPLE
$Remove = @(“CCMAIL:”,”fabrikam.com”)
.\Remove-ExchangeProxyAddresses.ps1 -StringsToRemove $Remove
Removes strings “CCMAIL:” and “fabrikam.com” from all recipient types.
.EXAMPLE
$Remove = @(“CCMAIL:”,”fabrikam.com”)
.\Remove-ExchangeProxyAddresses.ps1 -StringsToRemove $Remove -RecipientTypes Mailbox
Removes strings “CCMAIL:” and “fabrikam.com” from only mailboxes.
Thanks for this! – Are you able to add a log file, just so it outputs the processed/removed addresses into a csv?
Yes, you could do something like “Add-Content $address -Path output.txt” above each removeat($i) line.
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
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!
Forgot to say that’s first time I noticed you could count backwards with .-1 and i–
Always learn something new here:)
Thanks again
Oh, yes–just like other languages, ++ and — increment/decrement by one.
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/
Great stuff as usual
Thanks