Link to home
Start Free TrialLog in
Avatar of Michael Leonard
Michael LeonardFlag for United States of America

asked on

need assistance with powershell script to remove email aliases

hello, we need to remove aliases from 10 different namespaces.. for example. user john smith has these aliases that we want to remove.
jsmith@xyz.com,  jsmith@dev-a.com,  jsmith@ops-a.com  etc.

we have approx.  50 different namespaces with aliases to remove off of 100+ accounts.

can someone provide a powershell script we can run to seek and remove all aliases from the 50 different email namespaces?

here is some example powershell logic that would remove a set of aliases from one mailbox, we need to do this for multiple:
Set-Mailbox "Janet Schorr" -EmailAddresses @{remove="janet.schorr@corp.contoso.com","janets@tailspintoys.com"}

Open in new window


I found this code but can't get it to work in bulk:
$ users = Get-mailbox | where {$ _.emailaddresses-like "* XXX.com.br *"}
foreach ($ a in $ users) {$ a.emailaddresses.Remove ("$ ($ a.alias) @ YYY.com.br")}
$ users |% {Set-Mailbox $ _.Identity-EmailAddresses $ _.EmailAddresses}

Open in new window


thx in advance
Avatar of Mahesh
Mahesh
Flag of India image

Try below code:

<# The script will remove all email addresses from list of mailboxes except "Primary SMTP" and "X400" and "X500"

Create one csv file with "mailboxes" as header and add all mailbox names underneath
# Ex: 

Mailboxes
user1
user2
user3
 
#>

$Allmbx = Import-Csv "C:\mbx\mailboxes.csv"

foreach ($mbx in $allmbx) {

$mymailbox = Get-Mailbox -Identity $mbx.mailboxes -ErrorAction SilentlyContinue

If ($mymailbox -ne $null) {

$mymailbox.EmailAddresses | ?{ ($_.IsPrimaryAddress -ne $true) -And ($_.PrefixString -ne "X400") -And ($_.PrefixString -ne "X500") } | % {Set-Mailbox $mymailbox -EmailAddressPolicy $false -EmailAddresses @{Remove=$_} }

  }

}

Open in new window


Mahesh.
Avatar of Michael Leonard

ASKER

hi Mahesh - in our case, we only need to remove specific SMTP aliases, not strip out all but the primary.

thx - S.
then its as good as entering all required aliases in "Proxyaddreses" column in csv for every user and then remove with ForEach loop

csv file need to be prepared like below
mailbox,Proxyaddress1,proxyaddress2,proxyaddress3
user1,user@a.com,user@b.com,user@c.com
Ex:
$Allmbx = Import-Csv "C:\mbx\mailboxes.csv"

foreach ($mbx in $allmbx) {

$mymailbox = Get-Mailbox -Identity $mbx.mailboxes -ErrorAction SilentlyContinue

If ($mymailbox -ne $null) {

Set-Mailbox $mymailbox -EmailAddressPolicy $false -EmailAddresses @{Remove=$mbx.proxyaddress1,$mbx.proyaddess2} }

  }

}

Open in new window


But with above approach still there is manual work involved, better you remove all proxy addresses except primary as per 1st comment
OR may be somebody else can provide you better script
Mahesh this is not what we are looking for, we need powershell logic that will allow us to simply list the 50 + namespaces and the script to go through each account and remove any aliases with those specified email namespaces. we do not plan to go your route and prep every single individual alias for 1000+ accounts.

Qlemo are you around to assist with this?

thx - S.
In your example code
Set-Mailbox "Janet Schorr" -EmailAddresses @{remove="janet.schorr@corp.contoso.com","janets@tailspintoys.com"}

Open in new window

you are using different name parts:  janet.schorr and janets. Do we need to cope with that, or is it just the namespace (domain) which differs?
Is it likely that we need to touch all users, and/or remove all namespaces from each?
hi Qlemo - that was just some example code we came across, the one that we need is bulk removal:

$ users = Get-mailbox | where {$ _.emailaddresses-like "* XXX.com.br *"}
foreach ($ a in $ users) {$ a.emailaddresses.Remove ("$ ($ a.alias) @ YYY.com.br")}
$ users |% {Set-Mailbox $ _.Identity-EmailAddresses $ _.EmailAddresses}

Open in new window


this was we could cycle though all 1000+ accounts and remove any email addresses with [in this case @xxx.com.br]
Mahesh this is not what we are looking for, we need PowerShell logic that will allow us to simply list the 50 + namespaces and the script to go through each account and remove any aliases with those specified email namespaces

So you want to strip of specific domain email addresses from all users, right? - may be you are having 50 domains....
yes that's correct.  thanks
This should be reasonable in performance, since removes are only done once for each mailbox. But it has to process each mailbox, and that will need time.
$RemoveDomains = 'y.z', 'a.b'

Get-Mailbox |
% {
  $ToRemove = @()
  foreach ($dom in $RemoveDomains)
  {
    $ToRemove += $_.EMailAddresses.AddressString -like "*@$dom"
  }
  if ($ToRemove)
  {
    Write-Host -f yellow "Found $($ToRemove.Count) aliases to remove from $($_.Identity)"
    Set-Mailbox $_ -EMailAddresses @{remove = $ToRemove}
  }
}

Open in new window

thanks Qlemo -  I will test today and provide feedback
Try below code:
Get-Mailbox -ResultSize Unlimited | foreach {
for ($i=$_.EmailAddresses.Count;$i -ge 0; $i--)
{
if ($_.EmailAddresses[$i].ProxyAddressString  -like “smtp:*@domainA.com” -or $_.EmailAddresses[$i].ProxyAddressString  -like “smtp:*@domainB.com”)
	{
	$_.EmailAddresses.RemoveAt($i)
	}

}

$_|set-mailbox
    }

Open in new window


Check if this can help you.
U can add as many domains as you want in if statement
Mahesh, that is no reasonable approach for anything going beyond a few domains ;-).
hi Qlemo - here is the error code I'm seeing when running your script:

Cannot process argument transformation on parameter 'EmailAddresses'. Cannot convert value "System.Collections.Hashtabl
e" to type "Microsoft.Exchange.Data.ProxyAddressCollection". Error: "Conversion from System.Boolean to Microsoft.Exchan
ge.Data.ProxyAddress has not been implemented."
    + CategoryInfo          : InvalidData: (:) [Set-Mailbox], ParameterBindin...mationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Set-Mailbox

Open in new window

I've tested successfully with MSX 2013 and a single mailbox.
What is the output in yellow? What's your Exchange release?
hi Qlemo - client is running exchange 2010 sp3 latest roll-up

the output in yellow is "found 2 aliases to remove.."
That should work. 2010 isn't much different from 2013. But I now see the (generic) issue: If there is only a single email address defined, the result type of -like changes from [String[] to [Boolean].
$RemoveDomains = 'y.z', 'a.b'

Get-Mailbox |
% {
  $ToRemove = @()
  foreach ($dom in $RemoveDomains)
  {
    $ToRemove += @($_.EMailAddresses.AddressString) -like "*@$dom"
  }
  if ($ToRemove)
  {
    Write-Host -f yellow "Found $($ToRemove.Count) aliases to remove from $($_.Identity)"
    Set-Mailbox $_ -EMailAddresses @{remove = $ToRemove}
  }
}

Open in new window

hi Qlemo - just tested and the script runs now without any errors and finishes, however the aliases are not removed from the mailboxes.
According to the debug output, aliases are found? As said, I've tested, and it works fine on my side - and it should, if you do not get errors. Maybe replication issues between domain controllers? Did you test with a single account?
hi Qlemo when I run the script I do not see the yellow debug output saying "found 2 aliases to remove"  . is there anyway to have it generate some more verbose logging?
If you do not see something yellow, there is nothing found.
Of course we can add more output, like:
$RemoveDomains = 'y.z', 'a.b'

Get-Mailbox |
% {
  Write-Output -f yellow -NoNewLine "Processing $($_.Identitiy)"
  $ToRemove = @()
  foreach ($dom in $RemoveDomains)
  {
    $ToRemove += @($_.EMailAddresses.AddressString) -like "*@$dom"
  }
  if ($ToRemove)
  {
    Write-Host -f yellow "- found $($ToRemove.Count) aliases to remove from $($_.Identity)"
    Set-Mailbox $_ -EMailAddresses @{remove = $ToRemove}
  } else {
    Write-Host -f yellow '- nothing to remove'
  }
}

Open in new window

This will display one line per account.
hi qlemo - I get -nothing to remove when running the script, even though those email domains / aliases are listed on the account. i'm testing with a single mailbox using get-mailbox -identity extest
What does    get-mailbox extest | % { $_.EMailAddresses.AddressString }    display? If you see nothing,  remove .AddressString and try again.
hi Qlemo - when I run    get-mailbox extest | % { $_.EMailAddresses.AddressString }  I get no results, when I remove .Addressstring. it lists all of the email addresses
it works now, I just removed .addressstring from the script
thanks very much Qlemo much appreciated
hi Qlemo -

we are running the script but its not working in bulk, it works fine when we use get-mailbox -identity "jsmith" |

but if we run it with get-mailbox  [in bulk] it does not remove any of the aliases.

please advise.. thx
Of course I assumed you tested with both cases ;-)
I assume it depends on the mailbox account's data which gets processed. I don't think "it does not remove any of the aliases" is true, it might not do for specific accounts, but does for others. Again, what is the script output telling? Does it always report "nothing to remove"?

You can test the complete script almost unchanged by using get-mailbox -ResultSize 10 to only get the 10 first mailboxes.

You can run a different test get-mailbox | ? { @($_.EMailAddresses) -like '*@x.y' } | Select Identity  to get the mailboxes which should receive changes if only checking for a single domain x.y.
I've again tested it against our MSX 2013 in bulk, where users have one or more EmailAddresses entries, but the only issues I found were with the first debug output line.
To make changes more prominient I have changed the output to green if email addresses get removed.
$RemoveDomains = 'y.z', 'a.b'

Get-Mailbox |
% {
  Write-Host -f yellow -NoNewLine "Processing $($_.Identity)"
  $ToRemove = @()
  foreach ($dom in $RemoveDomains)
  {
    $ToRemove += @($_.EMailAddresses) -like "*@$dom"
  }
  if ($ToRemove)
  {
    Write-Host -f green "- found $($ToRemove.Count) aliases to remove from $($_.Identity)"
    Set-Mailbox $_ -EMailAddresses @{remove = $ToRemove}
  } else {
    Write-Host -f yellow '- nothing to remove'
  }
}

Open in new window

hi Qlemo - when I run this command I see almost 1000 results:
get-mailbox | ? { @($_.EMailAddresses) -like '*@target.es' } | Select Identity  

however when I run your script  - I loops through the accounts but only displays the yellow "nothing to remove"
this is Exchange 2010 SP3 .. we are not running ex 2013.  thx
2010 and 2013 are very similar, so it should work for both, But I cannot test with 2010.
it works when I target a single mailbox only on 2010.. when targeting in bulk it does not work.
hi Qlemo -

**update

I now see the ones it will remove in green but it fails on this error:
Pipeline not executed because a pipeline is already executing. Pipelines cannot be executed concurrently.
    + CategoryInfo          : OperationStopped: (Microsoft.Power...tHelperRunspace:ExecutionCmdletHelperRunspace) [],
   PSInvalidOperationException
    + FullyQualifiedErrorId : RemotePipelineExecutionFailed

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Qlemo
Qlemo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks Qlemo -  it is working now