Myth 1:
Migrating
Exchange mailboxes from one org to another without 3rd
Party tools is suicide
FALSE
In my last large
cross-org migration project, we moved roughly 30,000 mailboxes
using the standard Exchange 2007 "Move-Mailbox" PowerShell
command. The syntax is described here:
http://technet.microsoft.com/en-us/library/aa997599.aspx.
Having said that let
me point out that you should augment that command with
additional scripts that provide additional error-handling and
account management. In the end, the Move-Mailbox command is the
only tool I use to migrate terabytes of Exchange information
from one organization to another.
I
will show you the command in a moment, but first let's talk
about how we use it:
A)
For bulk
moves, we script the command against a text file that contains
the names we wish to migrate. I prefer this better than using an
AD group to list the migration candidates since it allows us to
"lock" the group and easily manipulate the names if so desired.
B)
Perform your AD work ahead of schedule.
Create Mail-enabled user objects in the target domain and
instruct the user community in advance as to how to change
passwords and logon. You should avoid using AD Contacts and
focus on Mail-enabled users in order to maintain passwords,
groups and other attributes before, during and after the moves.
This part of the project is critical and deserves its own
section as you must maintain all X500, SMTP attributes.
Moreover, it is important to cross-pollinate the
LegacyExchangeDN value in one directory as an X500 address in
the opposite directory for each mailbox. This will dramatically
reduce and possibly eliminate reply failures and meeting
ownerships.

C)
Use the
Move-Migration script to Mailbox-enable the target object and
move the mail but use an outside process to handle all account
changes in the source domain. This will give you more control
and reliability of the source objects.
The Move-Mailbox script
can perform these functions but there is little in the way of
error-handling so if the AD is not responsive or there is a
connection failure during object modifications, the Move-Mailbox
command does not always recover. It is super reliable as a mail
migration tool and semi-reliable with its AD changes so focus on
its benefits and shore-up its weaknesses.
D)
Execute a
series of Post Scripts to perform any additional cleanup you may
require for the accounts and mailboxes. There will be plenty.
You will need a script to disconnect (do not delete in case you
need to reconnect later) the mailbox on the source object and to
turn it in to a Mail-enabled object with all the previous
addresses and mail attributes. You will need another script to
compare the object to make sure it is correct.
Just to make sure my point is perfectly clear,
this is the exact code we use for every migration:
Param([string]$textfile,[string]$database)
$import = Get-Content $textfile
$SourceCredential =
get-credential
$TargetCredential =
get-credential
$targetGC =
"DC2.targetcompany.com"
$sourceGC =
"DC2.sourcecompany.com"
#move the migrated user's mailbox
$report = "g:\migrations\results\MailboxMove-$(Get-Date
-format 'yyyy-MM-dd hh-mm-ss').xml"
Move-Mailbox -Identity $item -TargetDatabase
$database -GlobalCatalog $targetGC -SourceForestGlobalCatalog $sourceGC
-SourceForestCredential $SourceCredential -TargetForestCredential
$TargetCredential -confirm:$False -RetryInterval 00:00:30 -BadItemLimit
50000 -IgnorePolicyMatch -AllowMerge -ReportFile $report
}
It is very, very simple. We create variables
for the credentials and the Domain Controllers and allow the
target database to be entered as a string so the execution of
the migration looks something like this:
./migrationscript
-textfile "C:\Group1.txt" -database "SERVERA\Storage Group
01\Database-01"
So let me explain a few
of the details in this script. First, we force the retry
interval to 30 seconds instead of the default 60. This is
important since there is a delay between the time you write the
object in AD and when the target Exchange server acknowledges
the write. Also, there is a bug in the Move-Mailbox script that
reports “Failed to set basic mailbox information, will retry in
60 seconds. ” I detailed the work-around here:
http://www.outlookexchange.com/Articles/Stevebryant/bryant_c18.asp
In short, you are likely to see this message
when performing cross-forest migrations:
"Failed to set basic mailbox information,
will retry in 60 seconds"
Microsoft should rename this function to
"Waiting" instead of "Failed" and you should just consider this
30 seconds part of the migration and move on!
Second, we set the BadIemLimit to a high
number but we have NEVER seen a SINGLE item get dropped. Lastly,
we added the IgnorePolicyMatch and -AllowMerge in order to meet
our own goals.
TimeSaver-Make sure all of the
target Exchange 2007 servers only have one Storage Group and one
Mail Store. In bulk migrations, we found that roughly 5% of the
migrations resulted in a (complete) disconnected mailbox in the
designated target store and an empty connected mailbox in a
completely different store. It seems that at some point during
the end of a mailbox migration, the target server cannot enable
the mailbox and Move-Mailbox creates a new empty mailbox on the
same server on a different store. No error is flagged and the
only way to detect this was to write a script:
get-mailboxserver | where {$_.name -like
"SERVERNAME*"} |Get-mailboxStatistics | where {$_.DisconnectDate
-notlike "" -and $_.Displayname -notlike "*test*"} | sort
LastLogonTime | ft DisplayName, LastLogonTime, Database -wrap
This script is pretty simply as it is only
looking to see if there are mailboxes that are in a disconnected
state. This will be the case if the mailbox has been moved to
another database or server or if the mailbox suffered the
"split" problem as described.
However, by targeting a server with only a single
database you eliminate this problem and have no need for my
clever script.
|