This script can be used to move mailboxes, specified within a CSV input file, between mailbox servers. It will also update the MPS Resource Manager database.

# Author: Johan Vosloo
# Date: 12/10/2009
# Purpose: Bulk move mailboxes from a CSV input file.
# Disclaimer: This script is provided as-is without any support. The script was tested against HMC 4.0, Exchange Server 2007 SP1 and Powershell 1.0. Please test in a test environment prior to production use.      
# Process:      
# 1. Use the Exchange Management Shell to get the source server name with Get-ExchangeServer | Select Name      
# 2. Use the Exchange Management Shell to populate the input CSV file with Get-MailboxDatabase | where {$_.ServerName.Contains("sourceservername") -eq "true"} | Get-Mailbox | Select Alias,Database | Export-Csv C:\Temp\MbxsToBeMoved.csv –NoTypeInformation      
# 3. Change ‘Database’ field header to ‘TargetDB’      
# 4. Modify database/targetdb field entries as required in the CSV     
# 5. Change preferredDomainController in mailbox move script     
# 6. Run mailbox move script:     
# CSV Example:     
# Alias,TargetDB     
# bloggsj,mytargetservername 
$path = "C:\jv\MoveMailbox\MbxsToBeMoved.csv";
Write-Host;
Write-Host "*******************";
Write-Host "Move Mailbox Script" -Foregroundcolor Blue -Backgroundcolor White;
Write-Host "*******************";
Write-Host;
Write-Host "A CSV is required (i.e. $path)"
$Ver1 = Read-Host "CONTINUE script execution? [Y] to continue or [ANY OTHER KEY] to exit"
  if ($Ver1 -ne "Y")
  {exit;
  } 
Write-Host; 
Write-Host "Valid entries in CSV:" -Foregroundcolor Blue -Backgroundcolor White;
# Note: Checks are not performed to avoid scenarios where sourcedb = targetdb in this version of the script. This is the administrators responsibility.
Write-Host;
Write-Host "Alias,TargetDB";
Import-csv -path $path | 
foreach `
{ 
               $TDBs = Get-MailboxDatabase $_.TargetDB -ErrorVariable MyError -ErrorAction SilentlyContinue;
# Note: Checks are not performed to avoid scenarios where the Alias is invalid in this version of the script. This is the administrators responsibility.
    $A = $_.Alias
               Write-Host "$A,$TDBS";
}
If ($MyError -ne $null)`
{ 
               Write-Host;
    Write-Host "*******";
               Write-Host "Error" -Foregroundcolor Red -Backgroundcolor White;
    Write-Host "*******";
    Write-Host "Invalid TargetDB in CSV. Script terminating..." -Foregroundcolor Blue -Backgroundcolor White;
    Write-Host "Error Description:" -Foregroundcolor Blue -Backgroundcolor White;
    $MyError;
    Write-Host;
               exit;
} 
$Ver2 = Read-Host "CONTINUE moving ALL mailboxes in CSV? [Y] to continue or [ANY OTHER KEY] to exit"
  if ($Ver2 -ne "Y")
  {exit;
  }
Function SendMPSRequest([string]$xmlRequestStr)
{
  $oMpf = new-object -comobject "Provisioning.ProvEngineClient"
  $xmlResponseStr = $oMPF.SubmitTrustedRequest($xmlRequest.get_InnerXml());
  $xmlResponse = new-object "System.Xml.XmlDocument";
  $xmlResponse.LoadXml($xmlResponseStr);
  $xmlResponse;
}
[string]$xmlRequestStr = @"
<?xml version="1.0" encoding="utf-8"?>
<request>
  <data>
    <preferredDomainController>ad01.fabrikam.com</preferredDomainController>
    <user>CSVPopulated</user>
    <targetDatabase>CSVPopulated</targetDatabase>
  </data>
  <procedure>
    <execute namespace="Hosted Email 2007" procedure="MoveMailbox" impersonate="1">
      <before source="data" destination="executeData" mode="merge" />
      <after source="executeData" destination="data" mode="merge" />
    </execute>
  </procedure>
</request>
"@
[string]$excXmlStr = @"
<?xml version="1.0" encoding="utf-8"?>
"@
Write-Host
Write-Host "Starting procedure..." -Foregroundcolor Blue -Backgroundcolor White;
Write-Host
$CSV = Import-csv -path $path
Foreach ($line in $CSV)`
  {
    $mailbox = Get-Mailbox $line.Alias | Select Alias, DistinguishedName; 
    $userName = $mailbox.Alias;
    $userDN = $mailbox.DistinguishedName;
    $TDB = $line.TargetDB
    Write-Host "Moving $userName to $TDB..." -ForegroundColor White
    Write-Host 
    $xmlRequest = new-object "System.Xml.XmlDocument";
    $xmlRequest.LoadXml($xmlRequestStr);  
    $xmlRequest.request.data.user = "LDAP://" + $userDN;
    $xmlRequest.request.data.targetDatabase = $TDB;
    $xmlResponse = $null;
    $xmlResponse = SendMPSRequest($xmlRequestStr.ToString());
        if ($xmlResponse.Response.Data.User -ne $null)`
        {
            $MPSUser = New-Object System.Object;
            $MPSUser | Add-Member -Type NoteProperty -Name "DistinguishedName" -Value $userDN;
            $MPSUser | Add-Member -Type NoteProperty -Name "User" -Value $xmlResponse.Response.Data.user;
            $MPSUser | Add-Member -Type NoteProperty -Name "TargetDB" -Value $xmlResponse.Response.Data.targetDatabase;
            $MPSUser | FL;
        }
  }            
Write-Host;
Write-Host "********************************************************************************************************************************************************************************************";
Write-Host "Script execution complete. In pre-HMC4.0 Hosted Exchange Update Rollup 5 environments, please remember to run the Managed Email 2007::RepairExchangeObject procedure on all mailboxes moved." -Foregroundcolor Blue -Backgroundcolor White;
Write-Host "********************************************************************************************************************************************************************************************";
Write-Host;