0
votes

I am trying to move mailboxes to a new Exchange server on a different O365 tenant. This script is a portion of this move which attempts to list all Exchange Online users who have licenses, create a contact for each user pointing to their new email address, and forwards their email to their new address as well as their mailbox

#requires -Version 3 -Modules MSOnline
$mailboxlist = Get-Mailbox | Select-Object -Property userprincipalname | 
Get-MsolUser | Where-Object -Property islicensed -EQ -Value $true | 
Select-Object -Property firstname, lastname, userprincipalname | 
Where-Object -Property firstname -NE -Value $null | 
Format-list -AutoSize


#Begin foreach loop
foreach ($item in $mailboxlist)
{
   #Create the forwarding address
   $forwardingaddress = $item.firstname + '.' + $item.lastname + '@newdomain.com'
   #Check for a contact, add if not present
   If (!(Get-MailContact $forwardingaddress -ErrorAction silentlycontinue)){
        New-MailContact $forwardingaddress -ExternalEmailAddress $forwardingaddress
   }
   #assign forwarding address
   set-mailbox -ForwardingAddress $forwardingaddress -DeliverToMailboxAndForward $true

}

The result of the above is a $mailboxlist which is populated with first and last names and the users UPN which is also an email address. The result of $forwardingaddress is [email protected].

I don't think I am creating the initial data correctly for the foreach loop. I know that if I replace the $item.firstname with $_.firstname I get the same empty result. I would much appreciate if someone knowledgeable on the topic could assist.

Thanks!

Edit: Final config with Kiran's suggestion

#requires -Version 3 -Modules MSOnline
$mailboxlist = Get-Mailbox |  Get-MsolUser | Where-Object { ($_.islicensed -eq $true) -and ($_.firstname -ne $null) }


#Begin foreach loop
foreach ($item in $mailboxlist)
{
    #Create the forwarding address
    $forwardingaddress = $item.firstname + '.' + $item.lastname + '@newdomain.com'
    #Remove any spaces from the email address
    $forwardingaddress = ($forwardingaddress -replace " ","").trim()
    #Check for a contact, add if not present
    If (!(Get-MailContact $forwardingaddress -ErrorAction silentlycontinue))
    {
        New-MailContact $forwardingaddress -ExternalEmailAddress $forwardingaddress
    }
    #assign forwarding address
    Set-Mailbox -ForwardingAddress $forwardingaddress -DeliverToMailboxAndForward $true
}
1

1 Answers

1
votes

try this:

$mailboxlist = Get-Mailbox |  Get-MsolUser | 
    Where-Object { ($_.islicensed -eq $true) -and ($_.firstname -ne $null) } 

the UserPrincipalName of get-Msoluser accepts pipeline input by propertyname so you should just pipe the output of get-mailbox to get-msoluser

select-object should be preferred over format-* commands because of the type of objects that are created.

Use format* when you want to show data on the console.

The where-object clause allows you to create complex conditions so try to combine them where you can. This should be the flow of commands:

cmdlet | where-object { some condition(s)} | select properties