Exchange Script running against all, not input

I have the following script that I am having an issue with. When I run it against an input file, it still goes out and tries to work against the entire domain. I’m not sure how to correct it. Any suggestions?

$users=Import-Csv c:\temp\testuser.csv
Foreach ($name in $users) {
$addr=Get-Mailbox -Identity $name | select -expand emailaddresses | ft smtpaddress
$primary=Get-Mailbox -Identity $name | select PrimarySmtpAddress
Set-Mailbox -Identity $name -EmailAddresses $primary
foreach ($box in $addr) {
* if entry in $addr contains “” then add it to emailaddresses *
?{$box -like “"} | Set-Mailbox -Identity $name -EmailAddresses @{add=$box}
* if entry in $addr contains “” then add it to emailaddresses *
?{$box -like "”} | Set-Mailbox -Identity $name -EmailAddresses @{add=$box}

The input file just has one line for the test:



I haven’t worked with the Exchange PowerShell cmdlets before, so I don’t know if all the syntax in this answer will be right. There’s a lot going wrong in the code you posted from a general PowerShell standpoint, though:

  • $name is not a string. It's an object representing a single row of your CSV file. If your posted contents of the CSV are accurate, the object should have a propery named "userid" that contains the data you want. In the code posted below, I've renamed this variable to $object (to avoid confusion), and replaced references to $name with $object.userid .
  • You should only make one call to Get-Mailbox, and store its result in a variable. Piping the results to Select-Object is unnecessary, in this case, and piping them to Format-Table ("ft" in the code you posted) is wrong. Whenever you use one of the Format-* cmdlets, you've just gone from using an object to displaying a text representation of that object on screen or in a file.
  • I'm not sure what you're trying to accomplish in the foreach ($box in $addr) loop, but the syntax is definitely wrong. You can't start a pipeline with Where-Object (alias "?" in the code above); something has to be piped into it.

Here’s a start at revising the code. Since I’m not sure what you intend to do with the user’s mailbox once you’ve found it, I’ve ignored all of that code for now:

$users=Import-Csv c:\temp\testuser.csv

foreach ($object in $users) {
    $mailbox = Get-Mailbox -Identity $object.userid

    # You can access $mailbox.EmailAddresses and $mailbox.PrimarySmtpAddress here,
    # in place of the $addr and $primary variables you were using.

    # Do something with the mailbox (not sure what you are trying to do with it yet).

We have changed our domain a couple times and merged domains at least once since some of these accounts were created. We are doing a move to a new hybrid setup (including O365) and we need to strip the old addresses off the accounts that have them. The old domains no longer exist, and we no longer route mail for those domains, but the artifacts still exist on some accounts. I need to remove the artifacts, or set the correct ones as the only email addresses. The problem exists in that we have some people that have changed their email address (due to marriage or name changes) and we need to keep the legitimate, but old, addresses associated with them (i.e. is now Due to this, I can’t just split the Primary SMTP address and use that. We only want to keep the and addresses. Here is where I have gotten to so far, and I know it may not be the best way to code this:

ForEach ($object in Get-Content c:\temp\testuser.txt) {
Get-Mailbox -Identity $object | Select -Expand EmailAddresses | ft SmtpAddress > c:\temp\datause.csv
Get-Mailbox -Identity $object | Select PrimarySmtpAddress c:\temp\primary.csv
$primaryadd=(Get-Content c:\temp\primary.csv -TotalCount 4)[-1]
Set-Mailbox -Identity $object -EmailAddressPolicyEnabled $false -EmailAddresses $primaryadd
ForEach ($box in Get-Content c:\temp\datause.csv) {
# if entry in $addr contains “” then add it to emailaddresses *
?{$box -like “*”} | Set-Mailbox -Identity $name -EmailAddresses @{add=$box}
# if entry in $addr contains “” then add it to emailaddresses *
?{$box -like “*”} | Set-Mailbox -Identity $name -EmailAddresses @{add=$box}

As Dave said, you have a really big problem with this line:

Get-Mailbox -Identity $object | Select -Expand EmailAddresses | ft SmtpAddress > c:\temp\datause.csv

You are outputting format objects and not the text you want. If you want to display the addresses on the screen and send them to a file, then this is a better way to do it:

Get-Mailbox -Identity $object | Select -Expand EmailAddresses | Tee-Object -FilePath c:\temp\datause.txt

What I’m actually trying to get is the individual addresses so that I can remove addresses that no longer have a valid domain. and I’m having a hard time getting the Set part to work.

That’s good information (what you’re trying to do), but unfortunately I don’t know enough about the Exchange cmdlets to help with the specifics, and I don’t have an environment handy where I can play around with them.

I’ve installed Exchange 2013 on one of my test VMs, and it (with PowerShell) are making my head hurt. If I run the Exchange Management Shell and call Get-Mailbox, the EmailAddresses and PrimarySmtpAddress properties are objects of type [Microsoft.Exchange.Data.SmtpAddress]. If I connect to Exchange with Import-PSSession from a script (a technique I found in several Scripting Guy posts when I did a quick web search) and run the same command, those properties are strings instead (with the SMTP: / etc prefixes in the EmailAddresses collection). I’m not sure why the results are different.

That makes it kind of difficult to try to help with your script, because I don’t know what type of data it will have to deal with. Could just be that I’m an Exchange noob and doing something wrong.

if you just want to remove invaild emailaddresses you could try

$Mailboxes = Get-Mailbox
ForEach ($Mailbox in $Mailboxes) {
$newemail = @()
$email = $Mailbox| Select-Object -ExpandProperty Emailaddresses
$email | ForEach-Object {
if ($_ -notlike ‘invailddomainhere’) {
$newemail += $_
Set-Mailbox $Mailbox -EmailAddresses $newemail