Exchange Script running against all, not input

This topic contains 7 replies, has 4 voices, and was last updated by  Kevin Hopcroft 4 years, 3 months ago.

  • Author
    Posts
  • #9453

    Jason Klingensmith
    Participant

    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 "@eduation.edu" then add it to emailaddresses *
    ?{$box -like "*@education.edu"} | Set-Mailbox -Identity $name -EmailAddresses @{add=$box}
    * if entry in $addr contains "@ol.education.edu" then add it to emailaddresses *
    ?{$box -like "*@ol.education.edu"} | Set-Mailbox -Identity $name -EmailAddresses @{add=$box}
    }
    }

    The input file just has one line for the test:

    userid

    Jason

  • #9454

    Dave Wyatt
    Moderator

    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).
    }
    
  • #9469

    Jason Klingensmith
    Participant

    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. jane.smith@education.edu is now jane.thompson@education.edu). Due to this, I can't just split the Primary SMTP address and use that. We only want to keep the @education.edu and @ol.education.edu 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 “@eduation.edu” then add it to emailaddresses *
    ?{$box -like “*@education.edu”} | Set-Mailbox -Identity $name -EmailAddresses @{add=$box}
    # if entry in $addr contains “@ol.education.edu” then add it to emailaddresses *
    ?{$box -like “*@ol.education.edu”} | Set-Mailbox -Identity $name -EmailAddresses @{add=$box}
    }
    }

  • #9472

    Art Beane
    Member

    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
  • #9483

    Jason Klingensmith
    Participant

    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.

  • #9484

    Dave Wyatt
    Moderator

    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.

  • #9547

    Dave Wyatt
    Moderator

    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.

  • #9569

    Kevin Hopcroft
    Participant

    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
    }

You must be logged in to reply to this topic.