Site Collection Backup/Restore when using Local Term Groups

The introduction of service applications, starting in SharePoint 2010, has created a set of challenges that are often not realized until they bite you.  Such is the case with utilizing site collection backup/restore functionality while leveraging local term group capabilities of Managed Metadata.  These challenges can be overcome, but it requires some planning.

Managed Metadata provides two basic types of term groups:  “global” term groups and local term groups.  This post will deal with the latter.  A local term group is scoped to a site collection.  It gets created as soon as the first column of type “Managed Metadata” is created within the site collection.  Technically, it will be created as soon as the user clicks the “Customize your term set” option in the Add Column page.  This could be a site column or simply a column created in any list or library.  After the first Managed Metadata column is configured in a site collection, you will see an entry for the local term group in the Term Store Management tool  (https://<yoursite/_layouts/termstoremanager.aspx).  The local term group will appear below the dotted line (see screenshot below) and will be named “Site Collection - <relative site collection path with ‘/’ replaced by ‘-‘>”.

 

Term groups/terms are stored in the Managed Metadata service application, not in the content database.  To connect the term group to the site collection, a property named “SiteCollectionGroupId<MMS GUID>” is added to the site collection’s root web (example:  SiteCollectionGroupIdc2551cab-f91c-48ea-aee1-0ed07471625c).  The value of this property is the GUID of the local term group.  This property is a one-to-one mapping between a site collection and a MMS service application proxy.

Additionally, the term group contains a property called “SiteCollectionAccessIds”.  This property is a collection of site collection GUIDs and is used to control a site collection’s access to read/connect to the term group.

Get the Default Site Collection Term Store via PowerShell:

$site = Get-SPSite <site collection URL>

$tx = New-Object Microsoft.SharePoint.Taxonomy.TaxonomySession($site)

$termstore = $tx.DefaultSiteCollectionTermStore

$termstore

The output of the script is shown below.  Note that the “Id” property (marked with an “x”) is that value that gets placed in the web property discussed above.

Get the term groups via PowerShell:

$site = Get-SPSite <site collection URL>

$tx = New-Object Microsoft.SharePoint.Taxonomy.TaxonomySession($site)

$termstore = $tx.DefaultSiteCollectionTermStore

$termstore

Foreach ($termgroup in $termstore.Groups)

{

               $termgroup

}

The term group properties shown below are the output of the script above.  Note the “SiteCollectionAccessIDs” property, which contains the GUID of each site collection that can access the term group (usually contains one GUID).

Now here comes the issue.  When you create a site collection backup (Backup-SPSite) and restore it (Restore-SPSite), the site collection gets a new ID.  The GUIDs of the lists/items/etc. in the site collection will remain the same, but the site collection itself is given a new GUID.  The backup/restore process does not capture the local term group, so if you simply backup/restore the site collection, all columns connected to the term sets in the local term group will not work.  If you do not change the “SiteCollectionGroupID…” web property, a new term group will be created as soon as the first user creates a new Managed Metadata column. Term groups cannot be discreetly exported/imported without the GUIDs changing, which eliminates the potential to simply move the terms from the old local term group to the new local term group.

The best way to maintain the integrity of Managed Metadata columns that are connected to local term groups is to update the “SiteCollectionGroupID…” property and grant term group access as part of the backup/restore operation.  The following script can be used to update the property and grant access.

$site = Get-SPSite <site collection URL>

$tx = New-Object Microsoft.SharePoint.Taxonomy.TaxonomySession($site)

$termstore = $tx.DefaultSiteCollectionTermStore

$web = $site.RootWeb

# Link the restored site collection to the old local term group

# If this script is executed immediately after a restore of the site collection, the property shouldn’t exist. However, it is good to check for the existence of the property.

$webProp = $web.GetProperty(“SiteCollectionGroupId<MMS GUID>”)

If ($webProp –eq $null)

{

               $web.AddProperty(“SiteCollectionGroupId<MMS GUID>”, <term group ID – see script above to get this value>)

               $web.Update()

}

Else

{

               # Property exists – remove/re-add the property

               $web.DeleteProperty(“SiteCollectionGroupId<MMS GUID>”)

               $web.AddProperty(“SiteCollectionGroupId<MMS GUID>”, <term group ID – see script above to get this value>)

               $web.Update()

}

# Grant the restored site collection access to the old term store

$group = $termstore.Groups | Where-Object {$_.id –eq “term group ID”}

$group.AddSiteCollectionAccess($site.id)

$termstore.CommitAll()

$web.Dispose()

$site.Dispose()

 

If you want to create a new local term group and want to deprecate the terms in the old local term group, you can grant access (read-only) to the old local term group. This will enable users to continue using the old term sets, but will not allow updates to the term sets.  In SharePoint 2010, the “read-only” local term group will not appear in the Term Store Management tool, but the column will still function properly.  In SharePoint 2013, the “read-only” local term group will appear in the tool, but will be grayed out.  Use the following script to grant the restored site collection access to the old local term group without making the old local term group the site collection’s default local term group.

$site = Get-SPSite <site collection URL>

$tx = New-Object Microsoft.SharePoint.Taxonomy.TaxonomySession($site)

$termstore = $tx.DefaultSiteCollectionTermStore

# Grant the restored site collection access to the old term store

$group = $termstore.Groups | Where-Object {$_.id –eq “term group ID”}

$group.AddSiteCollectionAccess($site.id)

$termstore.CommitAll()

$site.Dispose()