Hello all!

A few months ago I ran into an interesting client. They decided that they wanted to do an email migration in addition to a domain migration… simultaneously. But first, I should set up a preface…

Please, please please please, PLEASE! PUUUUULLEAAASE! (That means I’m serious yo) If you are even slightly suspecting that you are going to bring in a consultant to help with your Office 365 migration, don’t do any set up before we get there. We hit the normal annoyances, like having to delete a bunch of data to clear accounts that were created before DirSync was set up. This normally isn’t a huge issue as you can link the accounts, but if you have a mailbox that you plan to migrate, and you activate a mailbox before DirSync, you’re gonna have a bad time. (Insert image macro here). We had to blast the accounts out, and that still didn’t get the full thing unlocked properly, I’m not entirely certain what happened, but apparently SkyDrive had some issues as well.

Now! Back to the specifics, so they decided that they wanted to set up DirSync and ADFS with their new domain, which didn’t have anyone in it. They used ADMT to migrate the accounts, which would have been fine, except they didn’t have an Exchange in their new domain. So the first thing I had to do was extend the schema to gather all those Exchange attributes. This was simple enough, and allowed me to fill in the rest of the attributes that were important.

Now the second problem we faced was that when you issue a remote move migration Office 365 looks locally for the remote Exchange attributes. (Mailbox GUID, Archive GUID, Hide in Address book) So we had to get those to the new domain. I am not certain if ADMT is capable of doing that, but my client didn’t want to use it so they asked me to come up with a solution. The first round of this I didn’t really understand how exporting to JSON or XML worked, so I had to do it with a CSV. This involved converting all the arrays into strings because if you try to export an array to a CSV in powershell, it shows up as system.array.object[]. I’ve later expanded my knowledge and learned the fine arts of exports to better formats, and frankly, I’ll never look back.

I used XML for these scripts because unfortunately you have to do some crazy stuff in the C# methods to get a JSON to work if it is over .5 MB. I wasn’t able to get it going properly so I gave up since I’m not getting paid by this client to do this work anymore. If anyone wants to explain the JSON methods below in the comments I’m super happy to update this!

Let’s get to the code though. The first is the Export:

Import-Module ActiveDirectory
$allUsers = Get-ADUser -Filter * -Properties *
$allUsers | Export-Clixml -Path .\Export.xml

The second script is the big guy, weighing in at 250~ lines, it will write all these attributes to your new AD.

Import-Module ActiveDirectory
$allUsers = Import-Clixml -Path .\export.xml
Set-Location AD:
foreach ($user in $allUsers) {
    $path = $user.distinguishedName
    if ($user.ExtensionAttribute1) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute1 -Value $user.ExtensionAttribute1
    }
    if ($user.ExtensionAttribute2) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute2 -Value $user.ExtensionAttribute2
    }
    if ($user.ExtensionAttribute3) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute3 -Value $user.ExtensionAttribute3
    }
    if ($user.ExtensionAttribute4) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute4 -Value $user.ExtensionAttribute4
    }
    if ($user.ExtensionAttribute5) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute5 -Value $user.ExtensionAttribute5
    }
    if ($user.ExtensionAttribute6) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute6 -Value $user.ExtensionAttribute6
    }
    if ($user.ExtensionAttribute7) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute7 -Value $user.ExtensionAttribute7
    }
    if ($user.ExtensionAttribute8) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute8 -Value $user.ExtensionAttribute8
    }
    if ($user.ExtensionAttribute9) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute9 -Value $user.ExtensionAttribute9
    }
    if ($user.ExtensionAttribute10) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute10 -Value $user.ExtensionAttribute10
    }
    if ($user.ExtensionAttribute11) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute11 -Value $user.ExtensionAttribute11
    }
    if ($user.ExtensionAttribute12) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute12 -Value $user.ExtensionAttribute12
    }
    if ($user.ExtensionAttribute13) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute13 -Value $user.ExtensionAttribute13
    }
    if ($user.ExtensionAttribute14) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute14 -Value $user.ExtensionAttribute14
    }
    if ($user.ExtensionAttribute15) {
        Set-ItemProperty -Path $path -Name ExtensionAttribute15 -Value $user.ExtensionAttribute15
    }
    if ($user.legacyExchangeDN) {
        Set-ItemProperty -Path $path -Name legacyExchangeDN -Value $user.legacyExchangeDN
    }
    if ($user.mail) {
        Set-ItemProperty -Path $path -Name mail -Value $user.mail
    }
    if ($user.MsExchArchiveGUID) {
        Set-ItemProperty -Path $path -Name MsExchArchiveGUID -Value $user.MsExchArchiveGUID
    }
    if ($user.MsExchArchiveName) {
        Set-ItemProperty -Path $path -Name MsExchArchiveName -Value $user.MsExchArchiveName
    }
    if ($user.msExchAssistantName) {
        Set-ItemProperty -Path $path -Name msExchAssistantName -Value $user.msExchAssistantName
    }
    if ($user.msExchAuditAdmin) {
        Set-ItemProperty -Path $path -Name msExchAuditAdmin -Value $user.msExchAuditAdmin
    }
    if ($user.msExchAuditDelegate) {
        Set-ItemProperty -Path $path -Name msExchAuditDelegate -Value $user.msExchAuditDelegate
    }
    if ($user.msExchAuditDelegateAdmin) {
        Set-ItemProperty -Path $path -Name msExchAuditDelegateAdmin -Value $user.msExchAuditDelegateAdmin
    }
    if ($user.msExchAuditOwner) {
        Set-ItemProperty -Path $path -Name msExchAuditOwner -Value $user.msExchAuditOwner
    }
    if ($user.msExchBypassAudit) {
        Set-ItemProperty -Path $path -Name msExchBypassAudit -Value $user.msExchBypassAudit
    }
    if ($user.MsExchBypassModerationLink) {
        Set-ItemProperty -Path $path -Name MsExchBypassModerationLink -Value $user.MsExchBypassModerationLink
    }
    if ($user.msExchELCExpirySuspensionEnd) {
        Set-ItemProperty -Path $path -Name msExchELCExpirySuspensionEnd -Value $user.msExchELCExpirySuspensionEnd
    }
    if ($user.msExchELCExpirySuspensionStart) {
        Set-ItemProperty -Path $path -Name msExchELCExpirySuspensionStart -Value $user.msExchELCExpirySuspensionStart
    }
    if ($user.msExchELCMailboxFlags) {
        Set-ItemProperty -Path $path -Name msExchELCMailboxFlags -Value $user.msExchELCMailboxFlags
    }
    if ($user.MsExchEnableModeration) {
        Set-ItemProperty -Path $path -Name MsExchEnableModeration -Value $user.MsExchEnableModeration
    }
    if ($user.msExchExtensionCustomAttribute1) {
        Set-ItemProperty -Path $path -Name msExchExtensionCustomAttribute1 -Value $user.msExchExtensionCustomAttribute1
    }
    if ($user.msExchExtensionCustomAttribute2) {
        Set-ItemProperty -Path $path -Name msExchExtensionCustomAttribute2 -Value $user.msExchExtensionCustomAttribute2
    }
    if ($user.msExchExtensionCustomAttribute3) {
        Set-ItemProperty -Path $path -Name msExchExtensionCustomAttribute3 -Value $user.msExchExtensionCustomAttribute3
    }
    if ($user.msExchExtensionCustomAttribute4) {
        Set-ItemProperty -Path $path -Name msExchExtensionCustomAttribute4 -Value $user.msExchExtensionCustomAttribute4
    }
    if ($user.msExchExtensionCustomAttribute5) {
        Set-ItemProperty -Path $path -Name msExchExtensionCustomAttribute5 -Value $user.msExchExtensionCustomAttribute5
    }
    if ($user.msExchHideFromAddressLists) {
        Set-ItemProperty -Path $path -Name msExchHideFromAddressLists -Value $user.msExchHideFromAddressLists
    }
    if ($user.msExchLitigationHoldDate) {
        Set-ItemProperty -Path $path -Name msExchLitigationHoldDate -Value $user.msExchLitigationHoldDate
    }
    if ($user.msExchLitigationHoldOwner) {
        Set-ItemProperty -Path $path -Name msExchLitigationHoldOwner -Value $user.msExchLitigationHoldOwner
    }
    if ($user.MsExchMailboxGuid) {
        Set-ItemProperty -Path $path -Name MsExchMailboxGuid -Value $user.MsExchMailboxGuid
    }
    if ($user.msExchMailboxAuditEnable) {
        Set-ItemProperty -Path $path -Name msExchMailboxAuditEnable -Value $user.msExchMailboxAuditEnable
    }
    if ($user.msExchMailboxAuditLogAgeLimit) {
        Set-ItemProperty -Path $path -Name msExchMailboxAuditLogAgeLimit -Value $user.msExchMailboxAuditLogAgeLimit
    }
    if ($user.MsExchModeratedByLink) {
        Set-ItemProperty -Path $path -Name MsExchModeratedByLink -Value $user.MsExchModeratedByLink
    }
    if ($user.MsExchModerationFlags) {
        Set-ItemProperty -Path $path -Name MsExchModerationFlags -Value $user.MsExchModerationFlags
    }
    if ($user.MsExchRecipientDisplayType) {
        Set-ItemProperty -Path $path -Name MsExchRecipientDisplayType -Value $user.MsExchRecipientDisplayType
    }
    if ($user.msExchRecipientTypeDetails) {
        Set-ItemProperty -Path $path -Name msExchRecipientTypeDetails -Value $user.msExchRecipientTypeDetails
    }
    if ($user.MsExchRemoteRecipientType) {
        Set-ItemProperty -Path $path -Name MsExchRemoteRecipientType -Value $user.MsExchRemoteRecipientType
    }
    if ($user.MsExchResourceCapacity) {
        Set-ItemProperty -Path $path -Name MsExchResourceCapacity -Value $user.MsExchResourceCapacity
    }
    if ($user.MsExchResourceDisplay) {
        Set-ItemProperty -Path $path -Name MsExchResourceDisplay -Value $user.MsExchResourceDisplay
    }
    if ($user.MsExchResourceMetaData) {
        Set-ItemProperty -Path $path -Name MsExchResourceMetaData -Value $user.MsExchResourceMetaData
    }
    if ($user.MsExchResourceSearchProperties) {
        Set-ItemProperty -Path $path -Name MsExchResourceSearchProperties -Value $user.MsExchResourceSearchProperties
    }
    if ($user.msExchRetentionComment) {
        Set-ItemProperty -Path $path -Name msExchRetentionComment -Value $user.msExchRetentionComment
    }
    if ($user.msExchRetentionURL) {
        Set-ItemProperty -Path $path -Name msExchRetentionURL -Value $user.msExchRetentionURL
    }
    if ($user.MsExchSenderHintTranslations) {
        Set-ItemProperty -Path $path -Name MsExchSenderHintTranslations -Value $user.MsExchSenderHintTranslations
    }
    if ($user.msExchTeamMailboxExpiration) {
        Set-ItemProperty -Path $path -Name msExchTeamMailboxExpiration -Value $user.msExchTeamMailboxExpiration
    }
    if ($user.msExchTeamMailboxOwners) {
        Set-ItemProperty -Path $path -Name msExchTeamMailboxOwners -Value $user.msExchTeamMailboxOwners
    }
    if ($user.msExchTeamMailboxSharePointLinkedBy) {
        Set-ItemProperty -Path $path -Name msExchTeamMailboxSharePointLinkedBy -Value $user.msExchTeamMailboxSharePointLinkedBy
    }
    if ($user.msExchTeamMailboxSharePointUrl) {
        Set-ItemProperty -Path $path -Name msExchTeamMailboxSharePointUrl -Value $user.msExchTeamMailboxSharePointUrl
    }
    if ($user.msExchUsageLocation) {
        Set-ItemProperty -Path $path -Name msExchUsageLocation -Value $user.msExchUsageLocation
    }
    if ($user.MsExchImmutableID) {
        Set-ItemProperty -Path $path -Name MsExchImmutableID -Value $user.MsExchImmutableID
    }
    if ($user.proxyAddresses) {
        Set-ItemProperty -Path $path -Name proxyAddresses -Value $user.proxyAddresses
    }
    if ($user.userCertificate) {
        Set-ItemProperty -Path $path -Name userCertificate -Value $user.userCertificate
    }
    if ($user.userSMIMECertificate) {
        Set-ItemProperty -Path $path -Name userSMIMECertificate -Value $user.userSMIMECertificate
    }
}
Expand

So you’ll need to run the first one on your old domain. I would run it with at least PowerShell 3.0, I’m not sure how the Export-CliXml command works in 2.0. And then run the second one in your new domain, also 3.0 or later on the PowerShell.

That should update all your attributes, which will allow you to migrate mailboxes from a domain that is not DirSync’d to Office 365.

Leave a Reply

Your email address will not be published. Required fields are marked *