On Windows PowerShell and other admin-related topics

Exchange Server 2010 Cross-Forest migration

In Exchange Server 2010 we can move mailboxes between forests when a forest trust are in place. This can be accomplished using the New-MoveRequest cmdlet from the Exchange Management Shell as well as from the Exchange Management Console. Note that remote mailbox moves from legacy Exchange versions only can be accomplished from the Exchange Management Shell.
Before any move requests can be made there are some preparation that needs to be done in the target forest. The users from the source forest must be created in the target forest as mail-enabled users with some specific attributes. The mandatory attributes in addition to several others are described in this article on the Exchange Server TechCenter.

Microsoft has published a sample script, Prepare-MoveRequest, to assist with the preparation in the target forest. The script will create new mail-enabled users in the target forest with the required attributes from the source forest. While this works quite well, many administrators wants to use alternate methods such as Active Directory Migration Tool (ADMT) or Microsoft Identity Lifecycle Manager (ILM) to preserve additional attributes. Especially SIDHistory and passwords are common.
When these tools are used, the Prepare-MoveRequest script got a parameter named –UseLocalObject which tells the script to convert the local object to the required mail-enabled user. While this might work fine depending on the environment, we`ve seen several administrators reporting problems when using the Prepare-MoveRequest script after ADMT-migration. When the script doesn`t find or match any local user due to some missing attributes it rather creates new mail-enabled users. There are no switch to disable the creation of new users if a local object to use aren`t found. I did a test in a lab-environment trying to use Prepare-MoveRequest with the –UseLocalObject parameter to prepare an ADMT-migrated object. This resulted in a new user being created with some random numbers added to the displayname and samaccountname.


As an alternative to using the Prepare-MoveRequest sample script I`ve created another PowerShell-script named Invoke-MoveRequest, available from here. This script are intended for scenarios where the user objects are already migrated using e.g. ADMT. Note that you must exclude Exchange-attributes when using ADMT, otherwise attributes like msExchHomeServerName which we don`t want to be migrated will come along. Using this script we will migrate the necessary Exchange-attributes.

The script will do the following:

  1. Copy the attribute Mail from the source object to the target object
  2. Copy the attribute mailNickname from the source object to the target object
  3. Copy the attribute msExchMailboxGUID from the source object to the target object
  4. Set the attribute msExchRecipientDisplayType to –2147483642
  5. Set the attribute msExchRecipientTypeDetails to 128
  6. Copy the attribute msExchUserCulture from the source object to the target object
  7. Set the attribute msExchVersion to 44220983382016
  8. Copy the attribute proxyAddresses from the source object to the target object
  9. Set the target objects attribute targetAddress equilent to the source object`s  mail attribute
  10. Set the attribute userAccountControl to 514
  11. Run the Update-Recipient cmdlet on the target mail-enabled user to set LegacyExchangeDN and other default Exchange-attributes
  12. Create a new move request
  13. Enable the target object and unset “User must change password on next logon”

The attributes copied and set are according to the list of mandatory attributes in the TechNet-article mentioned above. The mandatory attributes like DisplayName who not are added to the script are already migrated by ADMT. I also considered adding the LegacyExchangeDN from the target object as an X500 address to the source object`s proxyaddresses to keep mail-flow between the forests after migration, however, it turns out that this are taken care of by the New-MoveRequest cmdlet.
All variables in the “Custom variables”-section on the top of the script must be set before running. The script are set up to process all users in a specified Organizational Unit in the source domain, however, you may customize this for your needs by e.g. using a CSV-file or setup some filtering using the Where-Object cmdlet. You may also copy additional attributes mentioned in the TechNet-article.
The computer you`re running the script from must have the Exchange Management Tools for Exchange Server 2010 and the free Quest PowerShell Commands for Active Directory.

The script needs additional functionality regarding logging and error-handling, I`ll update this post when I`ve done so. Feel free to further enhance the script yourself, and please let me know in the comments below if you have any suggestions.

Update 19.08.2010: Since my writing the Exchange team have posted an excellent post on Exchange 2010 Cross-Forest Mailbox Moves on their blog.


April 23, 2010 - Posted by | Exchange 2003, Exchange Server 2007, Exchange Server 2010, Exchange Server management, Scripting, Windows PowerShell |


  1. Hi Jan,

    I was using your script and it’s a life-saver, but I had trouble understanding one variable, and had to figure it out on my own 🙂 Microsoft documentation on Technet is very detailed, but a litle confusing regarding the “targetdeliverydomain” parameter and so on…

    May I suggest you rename “Domain A” or “Domain” or “Mailbox Database A” and place some more meaningfull things, like:

    #Custom variables, edit this section
    $TargetDatabase = “Database in target domain”
    $TargetDeliveryDomain = “”
    $SourceForestGlobalCatalog = “dc-01.source.local”
    $SourceForestCredential = Get-Credential -Credential “source.local\SourceForestAdministrator”

    #Connect to source forest to collect users to migrate
    Connect-QADService -Service $SourceForest | Out-Null
    $SourceForestUsersToMigrate = Get-QADUser -SearchRoot “source.local/Department A/Users”

    … so people can make a little better difference between source local and public domain, and target source and public domain.

    Maybe put a small drawing with for forest A and forest B with local names and public names of domains on it.


    great script, really a life-saver 🙂


    Comment by Andrija | July 7, 2010 | Reply

  2. Hi!

    Thanks for your feedback, I`ll have a look into it and update the post when done 🙂

    Comment by Jan Egil Ring | July 7, 2010 | Reply

  3. Hello. May I know the new invoke script has the linkedmailuser switch?

    Thank you.

    Comment by Thomas | September 11, 2010 | Reply

  4. Hi,

    Exchange 2003 to Exchange 2010 cross-forest migration.

    I have been using your Invoke-MoveRequest and this works perfectly in the LAB.
    When this is run in LIVE the msExchMailboxGUID is not copied correctly.
    If I view the msExchMailboxGUID in ADSIEdit the attribute does match in source and target when viewed in Hex, Octal, Decimal or Binary (the only ones you can Edit in manualty) but not the default Octet String. The value is different when viewed in Octet String.

    The mailbox will not migrate due to this miss match.

    Any advice is much appreciated!


    Comment by Matthew McCahey | July 13, 2011 | Reply

  5. Nice lines

    Comment by Arun Chaudhary | December 19, 2011 | Reply

  6. Hello,
    Can i use CSV file with users SamAccountName or proxyaddress instead of searching the source domain ?

    I tried to replace
    $SourceForestUsersToMigrate = Get-QADUser -SearchRoot “DomainA.local/Department A/Users”

    $SourceForestUsersToMigrate = import-csv c:\filename.csv


    Comment by shlomi salman | April 18, 2012 | Reply

  7. Hello,

    I want to use this script with CSV file that holds the SamAccountName or Email addresses of my users

    i tried to replace the
    $SourceForestUsersToMigrate = Get-QADUser -SearchRoot “DomainA.local/Department A/Users”

    $SourceForestUsersToMigrate = import-csv c:\filname.csv

    but it didn’t work

    can you help ?


    Comment by shlomi | April 19, 2012 | Reply

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: