Tuesday, August 14, 2012

Unable to on-board and off-board mailboxes in an Exchange HybridConfiguration

This blog post describes the situation where you are unable to move an Exchange Online (Office 365) mailbox to an on-premise Exchange 2010 server in a hybrid configuration.

If an Exchange Online mailbox is created via the Exchange 2010 Management Console, the ExchangeGUID of the MS Online Mailbox is not properly set in the remote-mailbox configuration of the Active Directory user object. In most cases this is no problem at all, but if you want to move an MS Online mailbox from the cloud to your on-premises Exchange 2010 server the process fails with the error "Exception has been thrown by the target of an invocation.".



This all took me a while to figure it out. I had a customer that had created about 5500 Active Directory users. During this stage the existing users needed to have an Exchange Online mailbox without removing them first, so we used the "create-remotemailbox" cmdlet to create all mailboxes in Exchange Online. In this cases some users who had an Exchange Online Kiosk subscription changed positions and the client wanted to off-board these mailboxes to on-premise (this was the business case). During these actions the process failed because the remote-moverequest process apparently compares the ExchangeGUID value on both sides. If they not match, the process will fail with this pretty unusable error.

If this happens you will need to copy the ExchangeGUID of the mailbox in Exchange Online and replace the ExchangeGUID value of the remote-mailbox setting on the Active Directory user.

Below you can find a script that I have created to do this for all your users at once.

Just some prerequisites before running this script:

  • You can only run this script by using elevated permissions of User Account Control is turned off;

  • You need the Exchange cmdlets, therefore you either run the script from within the Exchange Management Shell or you'll need to import the cmdlets for Exchange in your current powershell session.

First we are going to create a new session called "Remote" in our current powershell session to run the Microsoft Exchange Online cmdlets in. If you don't do this it will not work because the Exchange Online cmdlets are the same as the Exchange On-Premise cmdlets and they will interfere with each other if you run everything in the same session.
New-PSSession -Name remote #Creates a new local pssession to avoid cmdlets conflicts

After we have created the new session, the script needs to perform some actions in this session to create an output CSV file that we can use later on. This section of the script gets the userprincipalname and the ExchangeGUID from all Exchange Online mailboxes and saves them to a CSV file in the path "D:\temp".

Note: There are several ways to do this. I have chosen to use the "enter-pssession" and "exit-pssession" cmdlets.
Enter-PSSession -Name remote #Enters the new pssession to proces commands
    $cred = Get-Credential ""
    #creating a new remote powershell session to Microsoft Online
    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $cred -Authentication Basic -AllowRedirection
        Import-PSSession $Session
    # Recieving ExchangeGUID of all mailboxes in Microsoft Online and exports it to a CSV file
        $temp = Get-Mailbox -ResultSize unlimited | select userprincipalname,exchangeguid
        $temp | export-csv -Path d:\temp\export-o365-boxes.csv -NoTypeInformation
Exit-PSSession

In the following section we are going to use the created CSV file to check if the ExchangeGUID of the Exchange Online Mailbox matches the ExchangeGUID of the remote-mailbox attributes of the Active Directory user.
Start-Transcript -Path D:\temp\transcript.txt #writes all output into a transscript file
$csv = Import-Csv -Path d:\temp\export-o365-boxes.csv #imports the created CSV file
    foreach ($item in $csv) { # create a loop to check if ExchangeGUID matches the MSonline Mailbox GUID. If not this script sets the value ExchangeGUID
        $mbtemp = get-remotemailbox $item.userprincipalname
            Write-Host $item.ExchangeGuid "is cached from csv file" -ForegroundColor Green
            Write-Host $mbtemp.ExchangeGuid "is cached from get-mailbox"-ForegroundColor Magenta
        if ($mbtemp.exchangeguid -ne $item.exchangeguid) {
            Write-Host "No match. Writing GUID" $item.exchangeguid "into user" $mbtemp.userprincipalname -ForegroundColor Red
            set-remotemailbox $mbtemp.userprincipalname -ExchangeGuid $item.exchangeguid
        }
}
Stop-Transcript

The whole script you can download here:
<# 
MS Online sets local Exchange 2010 remotemailbox ExchangeGUID

Author: Cor (C.J.H.) Reinhard
Copyright: 2012, Unauthorized use from author prohibited

Version: 1.0
Create date: 14-08-2012
Last modification date: 14-08-2012

Notes:  Make sure script execution is set to unrestricted by running "Set-ExecutionPolicy -ExecutionPolicy unrestricted -Force"
  Make sure to run this script from within the Exchange Server 2010 Management Shell

Change history:
13-08-2012: First version, v0.1
14-08-2012: Added pssessions, v1.0

Nice to have:
#>

New-PSSession -Name remote #Creates a new local pssession to avoid cmdlets conflicts

Enter-PSSession -Name remote #Enters the new pssession to proces commands
 $cred = Get-Credential ""
 #creating a new remote powershell session to Microsoft Online
 $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $cred -Authentication Basic -AllowRedirection
  Import-PSSession $Session
 # Recieving ExchangeGUID of all mailboxes in Microsoft Online and exports it to a CSV file
  $temp = Get-Mailbox -ResultSize unlimited | select userprincipalname,exchangeguid
  $temp | export-csv -Path d:\temp\export-o365-boxes.csv -NoTypeInformation
Exit-PSSession 

Start-Transcript -Path D:\temp\transcript.txt #writes all output into a transscript file
$csv = Import-Csv -Path d:\temp\export-o365-boxes.csv #imports the created CSV file
 foreach ($item in $csv) { # create a loop to check if ExchangeGUID matches the MSonline Mailbox GUID. If not this script sets the value ExchangeGUID
  $mbtemp = get-remotemailbox $item.userprincipalname
   Write-Host $item.ExchangeGuid "is cached from csv file" -ForegroundColor Green
   Write-Host $mbtemp.ExchangeGuid "is cached from get-mailbox"-ForegroundColor Magenta
  if ($mbtemp.exchangeguid -ne $item.exchangeguid) {
   Write-Host "No match. Writing GUID" $item.exchangeguid "into user" $mbtemp.userprincipalname -ForegroundColor Red
   set-remotemailbox $mbtemp.userprincipalname -ExchangeGuid $item.exchangeguid
  }
}
Stop-Transcript

No comments:

Post a Comment