Migrate Legal Hold Information

Migrate Legal Hold Information

Ever had to do a tenant to tenant migration? Me neither, up until a few months ago. A large merger resulted in two organizations that had to merge there Office 365 tenants. There are a few vendors that can help you in migrating SharePoint Online or Exchange Online. So moving that data was easy. The goal was to write off one of the O365 environments. All data had to be migrated to other O365 tenant. Once all data is moved the old environment was decommissioned.

Legal Hold information

So the requirement was straight forward. Make it possible to turn off one of the environments. The migration vendors and tooling out there made it easy to migrate most of the content. Yet it turned out that migrating the existing legal hold information was difficult. Office 365 out of the box does not provide a solution to export all legal hold information. And there were no vendors providing a  tool that could migrate this type of data. So we ended up experimenting with the Compliance Center and PowerShell cmdlets. 

Compliance Center

With the 'new' compliance center you can view legal hold information. You can use the UI to find and export your legal holds. Luckily everything you can do through the UI can be done through PowerShell as well. So in order to keep all legal hold data, just two steps are required:

  1. Get all mailboxes including inactive ones
  2. Get legal hold information for this mailbox

We could not find legal hold information without retrieving the mailboxes first. Depending on the organization size you might have a large data set. Use the mailboxes retrieved to then get the Legal Hold information. This information can be retrieved using a Compliance Search. Once a Compliance Search is created it can be downloaded. Each download can be specified to contain a PST file per mailbox. Each PST file can then be stored. Make sure to save this information securely as it contains all emails per user. 

PowerShell and Compliance Cases

In order to work with Compliance Cases and PowerShell, you need to include some Exchange Modules. These modules differ from the normal exchange modules. In case you are working with the normal Exchange modules as well you are required to load them separately. Loading them separately can be done using a prefix option in the Import. 

#Connect to both Exchange as Protection and Security sets
$SccSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.compliance.protection.outlook.com/powershell-liveid/ -Credential $UserCredential -Authentication "Basic" -AllowRedirection
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication "Basic" -AllowRedirection
# Import Protection and Security with a prefix 
Import-PSSession $SccSession -AllowClobber -prefix cc
Import-PSSession $Session -AllowClobber

Once loaded you can use normal commands to retrieve all mailboxes. Keep in mind to load them all. Also, it makes sense to only retrieve mailboxes with a litigation hold. Based on that you can create a new Compliance Case. This case can be created with the New-ComplianceSearch. As we loaded with a prefix it becomes New-ccComplianceSearch. More details on the New-ComplianceSearch.


#Get all mailboxes 
$mailboxes = Get-Mailbox -IncludeInactiveMailbox -ResultSize unlimited | ? {$_.LitigationHoldEnabled -eq $true} | Sort-Object {$_.PrimarySmtpAddress}

# Create Compliance search and start it 
New-ccComplianceSearch -Name "Demo Export" -Description "Created to export all legalholds" 
        -ExchangeLocation $someArrayWithEmailAddresses -AllowNotFoundExchangeLocationsEnabled $true 

Start-ccComplianceSearch -Identity "Demo Export" 

Once you are done make sure to remove the active sessions using the Remove-PSSession.

Remove-PSSession $Session
Remove-PSSession $SccSession

It is a bit cumbersome to migrate legal holds. There is no clear documentation on what is supported. Nor is there tooling that makes it easy. Using PowerShell does speed up things. Keep in mind though that exporting sets can become slow depending on their size. Our best performance was reached using sets of 500GB. The documentation states 2 TB in their export limits but that only resulted in timeouts.

Leave a Reply