Backup and Restore Office 365 Groups

While working with a partner this weekend on a tenant to tenant migration, we had the need to migrate Office 365 groups.  There's not really a lot of information around on recreating groups and memberships, so I decided to put together a tool to help the effort.

The first thing to understand about Office 365 Groups is that they are like the marriage of a SharePoint site, A Yammer group (optionally), a distribution list, and a mailbox.  They incorporate features from all those services to create a new type of team collaborative work environment that spans multiple services already present in Office 365, as well as providing a foundation for new services on the horizon.  (For some cool content, check out some of what was discussed at Ignite: Office 365 Groups at Microsoft Ignite 2017 )

For my partner's purpose of their tenant to tenant migration, it was important to understand two pieces:

  • An Office 365 group stores email content (messages and conversations) in the mailbox
  • Files from the messages (as well as other files directly uploaded to the group) live in the accompanying SharePoint document librar

If you're going to embark on a tenant to tenant migration, you need to capture the email data and the site contents.  Group ownership and membership are managed via the Unified Group Links properties.

To back up the groups in a rudimentary fashion, you can simply run Get-UnifiedGroup.  However, that misses the ownership and membership information, so you also need to run Get-UnifiedGroupLinks (for each LinkType) and join them to the object, kinda like this:

 $UnifiedGroups = Get-UnifiedGroup -ResultSize Unlimited
Foreach ($Group in $UnifiedGroups)
{
Write-Host "$($Group.Name) [$i of $Count]"
$Sub = Get-UnifiedGroupLinks -Identity $Group.Identity -LinkType Subscribers
$Mem = Get-UnifiedGroupLinks -Identity $Group.Identity -LinkType Members
$Own = Get-UnifiedGroupLinks -Identity $Group.Identity -LinkType Owners
$Agg = Get-UnifiedGroupLinks -Identity $Group.Identity -LinkType Aggregators
$Group | Add-Member -TypeName NoteProperty -NotePropertyName Subscribers -NotePropertyValue ($Subscribers -join ",") -Force
$Group | Add-Member -TypeName NoteProperty -NotePropertyName Members -NotePropertyValue ($Members -join ",") -Force
$Group | Add-Member -TypeName NoteProperty -NotePropertyName Owners -NotePropertyValue ($Owners -join ",") -Force
$Group | Add-Member -TypeName NoteProperty -NotePropertyName Aggregators -NotePropertyValue ($Aggregators -join ",") -Force
}

Once you start looking at the output, you'll notice that the group memberships are stored using the account alias and not the SMTP address.  So, if you are moving tenants (and especially if you are merging with an existing tenant), you may not be able to get the same alias again.  Or, if you change aliases to match usernames, you want SMTP.  Or, if you reuse aliases after users are removed from your organization, you want SMTP.  Or, if something disastrous happens and you need to recreate and everyone gets new aliases, you need SMTP.  Basically, in almost every use case I could think of, you're better off having the SMTP address of your users.

So, you need to store those values as SMTP.

There are a ton of properties that, by default, store the alias value.  To resolve/select the primary SMTP address for each of those, I did something like this:

 # Resolve ModeratedBy
$ModeratedBy = @()
foreach ($addr in $Group.ModeratedBy) { $ModeratedBy += (Get-Recipient $addr).PrimarySmtpAddress }

At some point, this endeavor becomes a tool.

I approached the tool with the mindset of possibly needing to perform Office 365 groups migrations in multiple steps (such as exporting the groups from the source tenant, creating the groups in the new tenant, and then adding the users back once the domains are moved), so you can support data staging.

In a 1-stage migration, you can simply export the groups from the source tenant and import them into the target tenant with the users.  This depends on the users (and domains) being in the target tenant.

In a two-stage migration (which I envision will be most scenarios), you export the groups from the source tenant, and then import them into the target tenant.  At this point, you can begin staging data using your tool of choice.  In most tenant to tenant migrations, you don't move the domain until the end, so your users won't exist with the proper SMTP addresses in the target tenant until cutover time (meaning you might not be able to add them in).

In a divestiture scenario (where the divesting users are getting a new domain name), you may want to remap the user's domain suffix (assuming their alias to the left of the @ stays the same).  I've put a feature in for that as well.

Examples of usage:

Example 1 - Export unified groups

 .\ExportImportUnifiedGroups.ps1 -Mode Export -File MyUnifiedGroups.csv

In this example, you are exporting unified groups from a source tenant.

Example 2 - Import unified groups in a 1-stage migration

 .\ExportImportUnifiedGroups.ps1 -Mode Import -File MyUnifiedGroups.Csv -IncludeUsers

Import unified groups in a 1-stage migration (imports groups and users together).  This option assumes that the domains have been migrated.  Since users are resolved via SMTP address on export, the primary SMTP domains for the users must exist in the target environment.  If they don't, lots of red on the screen.

Example 3 - Import unified groups in a 2-stage migration (Stage 1)

 .\ExportImportUnifiedGroups.ps1 -Mode Import -File MyUnifiedGroups.csv

Import unified groups in a 2-stage migration (import groups only, no members or owners).  Since the users are resolved via SMTP address on the export, the primary domains for the users must exist in the target environment (is there an echo in here?).

Example 4 - Import unified groups in a 2-stage migration (Stage 2)

 .\ExportImportUnifiedGroups.ps1 -Mode Set -File MyUnifiedGroups.csv  

Import users and set additional properties of previously imported Unified Groups.  After the domains have been cut over, you re-process the export file and add the users back in.

Example 5 - Export unified groups with address rewrite 

 .\ExportImportUnifiedGroups -IncludeUsers -Mode Export -File MyUnifiedGroups.csv -RewriteTargetDomain -SourceDomain contoso.com -TargetDomain fabrikam.com 

If your organization is involved in a divestiture and the divesting entity is not retaining the primary SMTP address, you can rewrite the SMTP suffix with a new address space.  In this example, contoso.com is rewritten with fabrikam.com.  The resulting export file has rewritten addresses.

Example 6 - Import unified groups in a 1-stage migration with address rewrite

 .\ExportImportUnifiedGroups -IncludeUsers -Mode Import -File MyUnifiedGroups.csv -RewriteTargetDomain -SourceDomain contoso.com -TargetDomain fabrikam.com

If your organization is involved in a divestiture and the divesting entity is not retaining the primary SMTP address, you can rewrite the SMTP suffix with a new address space.  In this example, contoso.com is rewritten with fabrikam.com during the import process.  The original export file is not modified.

To download the tool, head over to the TechNet Gallery: https://gallery.technet.microsoft.com/Export-and-Import-Unified-e73d82ba.