Convert Exchange 2007 mailboxes to mail-enabled users after a staged Exchange migration

Convert Exchange 2007 mailboxes to mail-enabled users after a staged Exchange migration

Tim Heeney, Sr. Program Manager, Microsoft Services

Marc Nivens, Sr. Escalation Engineer, Exchange Server Support

Lou Mandich, Sr. Premier Field Engineer, Microsoft Services

If you’ve completed a staged Exchange migration to migrate your organization’s Exchange 2007 on-premises mailboxes to Office 365 and you want to manage cloud-based users from your on-premises organization—using Active Directory—you should convert the on-premises mailboxes to mail-enabled users (MEUs). Why? Two things happen after a mailbox is migrated to the cloud in a staged Exchange migration:

  • A user has an on-premises mailbox and a cloud mailbox.
  • Mail sent to the user’s on-premises mailbox is forwarded to their cloud mailbox. This happens because during the migration process, the TargetAddress property on the on-premises mailbox is populated with the remote routing address of the cloud mailbox. So users need to connect to their cloud mailboxes to access their e-mail.

This behavior results in two issues:

  • If a person uses Microsoft Outlook to open their mailbox, the Autodiscover service still tries to connect to the on-premises mailbox, and the user won’t be able to connect to their cloud mailbox. If there are users that haven’t been migrated to the cloud, you can’t point your Autodiscover CNAME record to the cloud until all users are migrated.
  • If an organization decommissions Exchange after all on-premises mailboxes are migrated to the cloud, messaging-related user information on the cloud mailbox will be lost. The Microsoft Online Services Directory Synchronization tool (DirSync) removes data (such as proxy addresses) from the cloud mailbox object because the on-premises mailbox no longer exists and DirSync can’t match it to the corresponding cloud mailbox.

So, what is the best solution to resolve these issues? Convert the on-premises mailbox to a mail-enabled user (MEU) in your on-premises organization after the user’s mailbox has been migrated to the cloud. When you convert an on-premises mailbox to an MEU:

  • The proxy addresses from a cloud-based mailbox are copied to the new MEU; if you decommission Exchange, these proxy addresses are still retained in Active Directory.
  • The properties of the MEU enable DirSync to match the MEU with its corresponding cloud mailbox.
  • The Autodiscover service uses the MEU to connect Outlook to the cloud mailbox after the user creates a new Outlook profile.

We’ve provided a Windows PowerShell script that you can run to convert Exchange 2007 mailboxes to MEUs. When you run this script, the proxy addresses from the cloud-based mailbox are copied to the MEU, which resides in Active Directory. Also, the properties of the MEU enable DirSync to match the MEU with its corresponding cloud mailbox.

We’ve also provided a PowerShell script that collects information from the cloud-based mailboxes.

You can run both of these PowerShell script in the Exchange Management Shell in your on-premises Exchange organization.

Best Practice: It’s recommended that you convert on-premises mailboxes to MEUs for a migration batch. After a staged Exchange migration batch is finished and you have verified that all mailboxes in the batch are successfully migrated and the initial synchronization of mailbox items to the cloud is complete, convert the mailboxes in the migration batch to MEUs.

Downloading the scripts

There are scripts to help you convert mailboxes to MEUs. Click the following links to download the scripts.

  • ExportO365UserInfo.ps1   Collects information from your cloud mailboxes and saves it to a CSV file. The Exchange2007MBtoMEU.ps1 script uses the information in the CSV file to bulk-create the MEUs.
  • Exchange2007MBtoMEU.ps1   Coverts on-premises Exchange 2007 mailboxes to MEUs

What do the scripts do?

Here’s a brief description of what each script does.

ExportO365UserInfo.ps1

This is a Windows PowerShell script that collects information about the cloud mailboxes that you migrated during the staged Exchange migration. It uses a CSV file to scope the batch of users. It’s recommended that you use the same migration CSV file that you used to migrate a batch of users.

When you run the ExportO365UserInfo script:

  • The following properties are collected from the cloud mailboxes for the users listed in the input CSV file:
    • Primary SMTP address
    • Primary SMTP address of the corresponding on-premises mailbox
    • Other proxy addresses for the cloud mailbox
    • LegacyExchangeDN
    • msExchMailboxGuid
  • The collected properties are saved to a CSV file named Cloud.csv

Exchange2007MBtoMEU.ps1

This a PowerShell script that you run in your on-premises Exchange 2007 organization to convert mailboxes to MEUs. It uses the Cloud.csv file, which is output by the ExportO365UserInfo script.

When you run the Exchange2007MBtoMEU.ps1 script, it does the following for each mailbox listed in input CSV file:

  • Collects information from the input CSV file and from the on-premises mailbox.
  • Creates a list of proxy addresses from the on-premises and cloud mailbox to add to the MEU.
  • Deletes the on-premises mailbox.
  • Creates a MEU and populates the following properties:
    • legacyExchangeDN   Value from the on-premises mailbox.
    • mail   The primary SMTP of the cloud mailbox.
    • msExchMailboxGuid   Value from the cloud mailbox.
    • proxyAddresses   Values from both the on-premises mailbox and the cloud mailbox.
    • targetAddress    Read from the on-premises mailbox; the value is the primary SMTP of the cloud mailbox.

Steps to convert on-premises mailboxes to MEUs

1.    Copy ExportO365UserInfo.ps1, Exchange2007MBtoMEU.ps1, and the CSV file used to run the migration batch to the same directory in your on-premises organization.

2.    Rename the migration CSV file to migration.csv.

3.    In the Exchange Management Shell, run the following command. The script assumes that the CSV file is in the same directory and is named migration.csv.

    .\ExportO365UserInfo.ps1

You will be prompted to use the existing session or open a new session.

4.    Type n and press Enter to open a new session.

5.    Enter the administrator credentials for your cloud-based organization and then click OK.

        The script runs and then saves the Cloud.csv file to the current working directory.

6.    Run the following command in a new Exchange Management Shell session. This command assumes that ExportO365UserInfo.ps1 and Cloud.csv are located in the same directory.

    .\Exchange2007MBtoMEU.ps1 <FQDN of on-premises domain controller>

    Example:

    .\Exchange2007MBtoMEU.ps1 DC1.contoso.com

        The script converts on-premises mailboxes to MEUs for all users included in the Cloud.csv.

 7.    Verify that the new MEUs have been created. In Active Directory Users and Computers, do the following:

  1. Click Action > Find
  2. Click the Exchange tab
  3. Select Show only Exchange recipients, and then select Users with external email address
  4. Click Find Now

        The mailboxes that were converted to MEUs are listed under Search results.   

8.    Use Active Directory Users and Computers, ADSI Edit, or Ldp.exe to verify that the following MEU properties are populated with the correct information.

    • legacyExchangeDN
    • mail
    • msExchMailboxGuid
    • proxyAddresses
    • targetAddress

3 out of 9 people found this post helpful.

Sort by: Published Date | Most Recent | Most Useful
Comments
  • I can't get this to work, if i get-mailbox from the command prompt for the user listed in the cloud.csv it returns correct results.  Yet running through the PS1 script all I get is inputobjectnotbound,Get-Mailbox error...

  • You need to add instructions to regarding script signing.  On my install of Exchange of 2010, I can't run those scripts.

  • Also, this is for a staged Exchange migration, yet it was linked from the cutover migration page (community.office365.com/.../835.aspx).  The instructions say, if you are running Exchange 2010, you can't do a staged migration.  Please clarify if this applies to Exchange 2010.

  • The scripts are not workiig in my environment. The first gives multiple errors and creates an empty cloud.csv file. I run the script, it does ask me for credentials, which I provide. I then get the following warnings:

    The term 'New-PSSession' is not recognized as a cmdlet, function, operable prog

    ram, or script file. Verify the term and try again.

    At C:\ANS_Util\Office 365 Migration\ExportO365UserInfo.ps1:19 char:20

    +     $s = New-PSSession  <<<< -ConfigurationName Microsoft.Exchange -Connectio

    nUri ps.outlook.com/powershell -Credential $cred -Authentication Basic

    -AllowRedirection

    The term 'Import-PSSession' is not recognized as a cmdlet, function, operable p

    rogram, or script file. Verify the term and try again.

    At C:\ANS_Util\Office 365 Migration\ExportO365UserInfo.ps1:20 char:35

    +     $importresults = Import-PSSession  <<<< -Prefix "Cloud" $s

    The term 'Get-CloudMailbox' is not recognized as a cmdlet, function, operable p

    rogram, or script file. Verify the term and try again.

    At C:\ANS_Util\Office 365 Migration\ExportO365UserInfo.ps1:37 char:70

    +     $MailBoxList = $MigrationCSV | %{$_.EmailAddress} | Get-CloudMailbox <<<<

    You cannot call a method on a null-valued expression.

    At C:\ANS_Util\Office 365 Migration\ExportO365UserInfo.ps1:53 char:52

    +             $CloudEmailAddress = $CloudEmailAddress.ToString( <<<< ).ToLower(

    ).Replace('smtp:', '')

    You cannot call a method on a null-valued expression.

    At C:\ANS_Util\Office 365 Migration\ExportO365UserInfo.ps1:58 char:113

    +         $UserInfo | Add-Member -Type NoteProperty -Name OnPremiseEmailAddress

    -Value $user.PrimarySMTPAddress.ToString( <<<< )

  • The 2nd script failed miserably when I ran them.

    So I was digging into why this script would fail (so that it won't fail when I run it on the 40+ users that I have to migrate as soon as I can show everything is stable)

    And it seems to me that the PS is using some built in CSV parser...

    This is a line from my cloud file

    LegacyExchangeDN,CloudEmailAddress,OnPremiseEmailAddress,MailboxGUID

    /o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=801169473de748bb8302e4a111a4b06f-jones, jane,jjones@mydomain.mail.onmicrosoft.com,jjones@mydomain.com,e92bd471-a185-4d40-b24b-6a30ae427800

    So the four columns are

    1 - /o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=801169473de748bb8302e4a111a4b06f-jones, jane

    2-  jjones@mydomain.mail.onmicrosoft.com

    3 - jjones@mydomain.com

    4 - e92bd471-a185-4d40-b24b-6a30ae427800

    So it seems to me that the Script dies when there's an embedded comma in the first column, as there is in this case.

    I am not a Powershell whiz... how could I prevent these commas from being misread as column delimiters?

    =====

    I was able to capture the error that happened to a different user but who's cloud file info contained the embedded comma in the first column's data

    The x500 value is x500:/o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/c

    n=Recipients/cn=a832db858fd64d89a68631c67b85a2c1-smith, john

    you can see below it chopped off everything after his last name

    Calling LookupADInformationFromSMTPAddress

    Adding x500:/o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/c

    n=Recipients/cn=a832db858fd64d89a68631c67b85a2c1-smith to EmailAddresses

    Adding x500:/o=BridgeNet/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=R

    ecipients/cn=jsmith to EmailAddresses

    Disabling Mailbox

    Enabling Mailbox

    Enable-MailUser : ExternalEmailAddress has an invalid value: The address 'john

    ' is not a valid SMTP address, so a prefix must be specified.

    At C:\Users\jpacella\Downloads\Migration\Exchange2007MBtoMEU.ps1:62 char:18

    +         Enable-MailUser <<<<   -Identity $UserInfo.Identity -ExternalEmailAdd

    ress $UserInfo.CloudEmailAddress -DomainController $DomainController

       + CategoryInfo          : InvalidData: (bridgenet.lan/B.../smith, john:

      ADObjectId) [Enable-MailUser], DataValidationException

       + FullyQualifiedErrorId : FD72BEAF,Microsoft.Exchange.Management.Recipient

      Tasks.EnableMailUser

    Hi! Any news about this issue? I´m running the first script but always the same error:

    You cannot call a method on a null-valued expression.

    At C:\maibox-to-mailenabledusers\ExportO365UserInfo.ps1:53 char:52

    +             $CloudEmailAddress = $CloudEmailAddress.ToString <<<< ().ToLower().Replace('smtp:', '')

       + CategoryInfo          : InvalidOperation: (ToString:String) [], RuntimeException

       + FullyQualifiedErrorId : InvokeMethodOnNull

    I´m on Exchange 2010 SP2, is it really necessary to complete this step? Thanks!!!

  • I fixed the error on 2010 where you get the error "You cannot call a method on a null-valued expression."

    Open the file in notepad and make the following changes to line 44:

    $CloudEmailAddress = $user.EmailAddresses | ?{($_ -match 'onmicrosoft') -or ($_ -cmatch 'SMTP:')}

    Basically you are changing the search to be an or instead of an and (since you probably won't have a .onmicrosoft in AD), and SMTP needs to be capitalized instead of lowercase.

    Enjoy!

    In new Office 365 this scripts work fine, users on the local exchange server is converted meu.  But when i restart Outlook again, it can't connect to Office 365. It ask credentials contuniously. It is trying to connect right place as 3016d08c-2bcb-....domain.com, but can't connect. When i try this with old version of Office 365, it works correctly. What can we do to setup this with Office 365 2013?

  • I also get the same problem:

    The term 'New-PSSession' is not recognized as a cmdlet, function, operable prog blah,blah,blah

    When I run the first script to generate the cloud.csv file.  Lots of red errors and an empty cloud.csv file is created.

    Im running Exchange Server 2007 SP2 on SBS 2008.

    Any ideas?

  • With the first script I had a problem after successful migration of 5 mailboxes (migrated each mailbox individually by creating respective migration.csv). When trying to migrate the 6th mailbox received the following error

    The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or

    the input and its properties do not match any of the parameters that take pipeline input.

       + CategoryInfo          : InvalidArgument: (:PSObject) [Get-Mailbox], ParameterBindingException

       + FullyQualifiedErrorId : InputObjectNotBound,Get-Mailbox

  • I had the same issue with this script, so I did the following after migrate the users to office 365 I use the same CSV and the following.

    Alias "Samaccountname" for the user, SMTP address "the Primary SMTP address for the User, and Externaladdress Samaccountname@domainname.onmicrosoft.com and run the following script.

    first one to disable the mailboxes for migrated users.

    second one to enable mail users for migrated users and it's working perfect so far with me, you can test it and let me know the results.

    Import-Csv Users.csv| foreach { Get-Mailbox -identity $_.Alias | Disable-Mailbox -Confirm:$false}

    Import-Csv Users.csv| foreach { enable-mailuser -identity $_.Alias  -PrimarySmtpAddress $_.SMTP -externalemailaddress $_.External }

  • I have just run this on one user and it worked great. Now that I am running it again for a second user I get "ldap  server unavailable" error.

    I have run NSLookup to the DC and it too cant connect.

    Any ideas?

  • I am having all kinds of trouble over the embedded commas issue. So far this is the only method offered to create a mail enabled user and it does not work. I have a pending ticket with MS about the problem and am getting no where. It seems to me that the issue would be simply resolved if the cloudLegacyExchangeDN value were created based on some other value than Display Name. As a result of using that parameter not only are there commas in the cloudLegacyExchangeDN but there are spaces as well. This is not consistent with any other use of Distinguished Name within AD. One change and the problem simply does not exist. Why in the world would anyone use Display Name at the end of 32 hex characters? Then create the x500 proxy address with the same value? Why?

    I suppose we could escape the extra comma when running the script but then the problem of users with longer names in which the comma does not appear requires that we have some code that checks that value for the extra comma and again, why should we have to do that? Remember that this is modifying the attributes of your users in AD. Surely I am not alone in having concerns about unexpected results from this script or including these values in AD. Or is this the reason for the disclaimer on the second script?

    Anyone else having this issue?

  • These scripts don't work on my Exchange 2007 install. I get errors about "get-pssession" not be recognized as a cmdlet. Can anyone add information about the requirements for these scripts? Any chance of getting manual instructions so we can still do this while the scripts are broken? I'm going to answer my own questions and say, "Probably not, because the author is no longer monitoring this page in anyway". None of the previous comments have been answered, so I doubt mine will be either.

  • "These scripts don't work on my Exchange 2007 install. I get errors about "get-pssession" not be recognized as a cmdlet."

    I had this error and had to update Powershell on the exchange Server to version 2.0.

    www.microsoft.com/.../details.aspx You'll need to download the correct version according to your server.

    Although now I get an error Get-CloudMailbox is not a recognised command. Anyone any thoughts on this. There seems to be a lot of people having issues with these scripts with help from Microsoft.....

Page 1 of 2 (18 items) 1|2|