As most of Hosted Messaging and Collaboration (HMC) companies start planning to migrate to Exchange 2010 SP2 hosted environment due to the change in strategy that was announced about the future of /hosting mode here, so most HMC customer have to move directly to Exchange 2010 SP2 in hosted mode as discussed here, and one of the activities come up to migrate from HMC to Exchange 2010 SP2 is Downsizing activity in the running HMC environment to utilize part of hardware to be reused in the new Exchange 2010 SP2 environment, and although it looks like a simple activity for some IT people but there are a lot of challenges that can be in some cases for some specific HMC components show stopper to continue the down activity, one of the important resource while working in this activity is Microsoft
Provisioning System SDK that can be downloaded from here.

In this post series I will share all my experience with HMC downsizing activity and explain how I deal with different challenges in this activity, in Part1 I covered the first step of HMC downsizing activity to select server roles that will be decommissioned, then covered most of preparations tasks in each of the selected roles.

 

In this post I will cover the preparations specific for Mailbox Role which is the most critical role of downsizing activity, and different preparations steps for Exchange MBX role can be divided as follows:

  • Validate that no Public folders in the selected MBX servers that are target for decommission or you will need to move public folder to another MBX server.
  • Verify which MBX server configured as Offline Address Book Server, OAB MBX server better to be excluded from MBX server list that are target for decommission or you have to move OAB from the target MBX server to another MBX server, to do this you can use “QueryAllServers.xml” that can be found under “Exchange 2007 OAB Resource Manager” folder, this query allow you to find which MBX Server configured as OAB Server
  • Verify which Business Organization (customers) allocated (in MPS Resource Manager) for which Exchange Mail Store, to do this verification you need to run “QueryOrganizationByMailstore.xml” that can be found under “Exchange 2007 Resource Manager” folder, new simple table can be created as below to list all Mailbox Servers, mailstores, and the allocated Organization per each mailstore, this table will be used in coming step after move mailboxes to verify that MBX servers that are target for decommission are not allocated for any organization any more (The good point is that you may find that some mailstores are empty and not allocated for any organization so you can easily delete these mailstores as per coming steps), you may need to stop provisioning new organization or new mailboxes at this stage to avoid creating new mailboxes on the mailstores that are target for decommission.

Mail Server

Mailstore

Organizations before Mailbox Move

After Mailbox Move

MBX01

MBX01-DB01

Org1.com
Org2.com
Org3.Net

 

MBX01-DB02

MBX02

MBX02-DB01

 

MBX02-DB02

  • Move Mailboxes from any mailstore in any of MBX server that is target for decommissioning, this mailboxes move should be done through MPS using PowerShell script, I used script described here as a base for the script I used as below after doing some tuning, and simply the script is read from CSV file the list of mailboxes that will be moved and call MPS to de-allocate resources for the moved mailboxes from original MBX mailstore and allocate it to the new MBX mailstore, and I remember here my college <Kip Ng> who help me fixing and tuning the script, the script I used is as below (You should note that there are some steps listed in the begging of the script and should be followed as a preparation steps before running the script), as a sample of generated CSV that script use is as follow:

PrimarySMTPAddress,TargetDB
Maged
@Org1.net,MBXV01\MBXV01SG01\MBXV01SG01DB01
Kip
@Org2.com,MBXV01\MBXV01SG01\MBXV01SG01DB01

And the used script is below:

# 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 PrimarySMTPAddress,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:    
# PrimarySMTPAddress,TargetDB    
# bloggsj,mytargetservername
$path = "C:\MailboxMove\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;
Write-Host;
Write-Host "PrimarySMTPAddress,TargetDB";
Import-csv -path $path |
foreach `
{
               $TDBs = Get-MailboxDatabase $_.TargetDB -ErrorVariable MyError -ErrorAction SilentlyContinue;
    $A = $_.PrimarySMTPAddress
               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.HMC.Local</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.PrimarySMTPAddress | Select PrimarySMTPAddress, DistinguishedName;
Write-Host $line.PrimarySMTPAddress
Write-Host $mailbox
    $userName = $mailbox.SameAccountName;
    $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;

Write-Host $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;

  • After successfully move all Mailboxes from target MBX Server/s to different MBX Server/s then you need to run step 3 again and complete the last column to be sure that mailstores in target MBX Servers are empty and not assigned for any organization.
  • Now you can remove the empty mailstores (after moving mailboxes and verifying that these mailstores are not allocated for any organization), this by running “RemoveExchangeResource.xml” under “Exchange Resource Manager” folder in MPS Engine Server.
  • Then you can run “QueryAllStore.xml” to verify that all mailstores in target MBX server/s were removed from MPS Resource Manager.

In the next post I will cover 3rd and 4th steps for downsizing activity, this will be coming soon, so be tuned.

As a conclusion HMC downsizing activity need some planning and should be done carefully to avoid any risk that can affect the HMC production environment.

 

Related Posts:

Part1: http://blogs.technet.com/b/meamcs/archive/2012/11/11/downsizing-hmc-environment-to-prepare-for-exchange-2010-sp2-hosted-solution-part1.aspx

Part2: http://blogs.technet.com/b/meamcs/archive/2012/11/12/downsizing-hmc-environment-to-prepare-for-exchange-2010-sp2-hosted-solution-part2.aspx 

Part3: http://blogs.technet.com/b/meamcs/archive/2012/11/19/downsizing-hmc-environment-to-prepare-for-exchange-2010-sp2-hosted-solution-part3.aspx