Migrating Managed Metadata Term Stores in SharePoint Server across Farms + Without ID changing

Managed Metadata in SharePoint 2010 is great until you want to move term groups or termsets with content types and site columns to another farm or environment. This is because the SharePoint is using GUID as reference when create a new metadata record, each GUID which used by site column will be regenerated even Import from delimiter file

We can export your managed metadata and import it into your other farm but the problem is that each termset and term has a GUID and when you import that data into your new farm, new GUID’s will be assigned to them. If you move the rest of your content to your new farm, your managed metadata columns, which point to those termsets won’t work anymore in your new farm because the GUID of the termset it links to, has changed. You have to hook them up again to the correct termset. Furthermore, existing items which already have values in those fields also need to be hooked up again. The value looks the same, but the ID is not and when you open the properties of such an item, SharePoint will not be able to resolve that value against the term store.

First let’s try with PowerSheel Script.

So, how do you move your managed metadata and keep the ID’s? It’s actually quite easy using PowerShell.

Export data

$mmsApplication = Get-SPServiceApplication | ? {$_.TypeName -eq “Managed Metadata Service”}

$mmsProxy = Get-SPServiceApplicationProxy | ? {$_.TypeName -eq “Managed Metadata Service Connection”}

Export-SPMetadataWebServicePartitionData $mmsApplication.Id -ServiceProxy $mmsProxy -Path \\server\share\mmsdata.cab

Copy this file to a location which is accessible to the database server of your destination farm.

make sure that the service account which is used to run the Managed Metadata Service has the “BulkAdmin” server role in SQL Server. This is role is only needed for the import. You can remove it afterwards.

Import data

$mmsApplication = Get-SPServiceApplication | ? {$_.TypeName -eq “Managed Metadata Service”}

$mmsProxy = Get-SPServiceApplicationProxy | ? {$_.TypeName -eq “Managed Metadata Service Connection”}

Import-SPMetadataWebServicePartitionData $mmsApplication.Id -ServiceProxy $mmsProxy -Path “\\server\share\mmsdata.cab” –OverwriteExisting

When you compare the termsets and terms of both farms, you will see that the ID’s are the same. Now you can move your content and your managed metadata columns will be working just fine.

Second approach is to using Server Object model code.

Luckily, the metadata GUID can be replicated and imported from/to Service Application by Microsoft.SharePoint.Taxonomy class. That mean implement the custom export/import process by either using .Net code or Powershell.

In this blog post I want to show you how to use the C# code with Taxonomy APIs to export and import managed metadata. At the same time I make a assumption you are experienced .Net development and with appropriate SharePoint knowledge.

First of all, ensure the account access to SharePoint has permission to read and write managed metadata store. I ‘m recommend using farm account when export and import metadata from/to SharePoint.

Here the exportation of the termsets and terms to xml.

  1. Create the SPSite object which link to managed service application which wish to export.

            SPSite site = new SPSite(siteUrl)

  1. Create a TaxonomySession and pass in SPSitecreated in step 1 as parameter.

 TaxonomySession session = new TaxonomySession(site);

  1. Retrieve TermStorecollection from session object created in step 2.

 TermStore MetadataTermStore = session.TermStores[managedMetadataServiceName];

  1. Iterate through terms collection and extract to XML file.

foreach (Group g in MetadataTermStore.Groups)

                {

                   // some code…….

    }

And the final view of your source code.

// This is the common library for xml extraction.

ManagedMetadata metaCommon = new ManagedMetadata();

using (SPSite site = new SPSite(siteUrl))

{

TaxonomySession session = new TaxonomySession(site);

TermStore MetadataTermStore = session.TermStores[managedMetadataServiceName];

foreach (Group g in MetadataTermStore.Groups)

{

XElement metaStore = metaCommon.GenerateNode(g);

}

}

The ManagedMetadata is the common class which I created for managed metadata to XML string, it provides several methods to extract metadata objects to xml element. For instance, below code using Linq to XML to generate Xelement from  metadata Group object.

public XElement GenerateNode(Group g)

{

XElement rElement = new XElement(GroupElementName, new XAttribute(NameKey, g.Name), new

XAttribute(GuidKey, g.Id),

from termSet in g.TermSets

select GenerateNode(termSet));

return rElement;

}

Please note when generating xml element you MUST include metadata’s GUID as it is important for import process.

I also create a Winform application to help me extract the managed metadata from SharePoint.

Your extracted xml should be something looks like this.

<?xml version=”1.0″ encoding=”utf-8″?>

<Group Name=”Example Group” Guid=”3eb956d1-2449-4eaf-be65-01579da93864″>

<TermSet Name=”Accounts” Guid=”d80de18e-6be1-4a4f-a157-1d1b64d17fe7″>

<Term Name=”Audit” Guid=”37ebd2d7-ad00-4c7f-a7b9-ad76ac3f0f57″ Lcid=”1033″ IsDeprecated=”false”>

<Term Name=”External” Guid=”f316c860-5727-46f7-9924-003e3c524c69″ Lcid=”1033″ IsDeprecated=”false” />

<Term Name=”Internal” Guid=”559c9a12-0a6c-4546-80e3-8770b5ecf39a” Lcid=”1033″ IsDeprecated=”false” />

</Term>

<Term Name=”Bank” Guid=”b9c52438-32f3-4597-950e-726ee9809774″ Lcid=”1033″ IsDeprecated=”false” />

<Term Name=”Budgets” Guid=”4741a838-f887-464f-93bf-1622ea5ad37d” Lcid=”1033″ IsDeprecated=”false” />

<Term Name=”B1″ Guid=”6876ff80-2e37-4d48-94b0-ecc4c962203e” Lcid=”1033″ IsDeprecated=”false”>

<Term Name=”B2″ Guid=”935bae00-b4fe-48fe-9260-660c27a62be6″ Lcid=”1033″ IsDeprecated=”false” />

<Term Name=”C2″ Guid=”546e29a3-a722-4b5f-80e7-5f4dc3b2355e” Lcid=”1033″ IsDeprecated=”false” />

</Term>

</TermSet>

</Group>

Above example shown you how to extract the managed metadata to XML, and the summary at below show you how to use Taxonomy’s API to import extracted xml into managed metadata store.

  1. Create the SPSiteobject which link to managed service application wish to export.
  1. Create a TaxonomySession and pass in SPSitecreated in step 1 as parameter.
  1. Retrieve TermStore collection from session object created in step 2.
  1. Iterate through extracted xml and import into term store, then commit.

Here how it looks like when implementing in C# code.

var meta = XElement.Load(loadLocation);

using (SPSite site = new SPSite(siteUrl))

{

TaxonomySession session = new TaxonomySession(site);

managedMetadataServiceName = “Managed Metadata Service”;

TermStore MetadataTermStore = session.TermStores[managedMetadataServiceName];

// My custom common library.

ManagedMetadata manageMeta = new ManagedMetadata();

manageMeta.NewNode(MetadataTermStore, meta);

MetadataTermStore.CommitAll();

}

The custom common library will takes XElement, Group, TermSet and Term object as parameter and create appropriate entry in metadata store. As above example, the library will extract Group, TermSets and Terms accordingly when pass in whole metadata Xelement.

When creating a new termset or term, you are expecting to pass in two parameters, term key and GUID. The GUID should be re-used the value extracted from managed metadata store. Example,

// t  is Xelement which extracted from XML string.

// Group is Taxonomy’s Group object.

Group.CreateTermSet(t.Attribute(NameKey).Value, new Guid(t.Attribute(GuidKey).Value));

// For create a new term under termset.

// ts is Taxonomy’s TermSet object.

// LCID is local integer value.

// t is Xelement.

ts.CreateTerm(t.Attribute(NameKey).Value, LCID, new Guid(t.Attribute(GuidKey).Value));

// or create a new term under another term.

// ts is Taxonomy’s Term object.

// t is Xelement.

ts.CreateTerm(t.Attribute(NameKey).Value, Convert.ToInt32(t.Attribute(LcidKey).Value), new

Guid(t.Attribute(GuidKey).Value));

My recommendation to seamlessly deployment for managed metadata is to using SharePoint WSP with feature, although you can write another bespoke tool for import but as best practice the SharePoint solution should always being used.

About Krishana Kumar

Krishana Kumar is SharePoint Architect/Trainer having Architecture experience with high volumes at Enterprise level and global scale - creation of highly scalable solutions with global user base and geographically distributed architectural components. Good knowledge of SharePoint best practices and governance models. I hold Two Master degree in Computer Science with over 11 years of experience working on Microsoft Technologies specially SharePoint, Project, .NET and other Information Worker Technologies. Having good exposer in Client side scripting Angular.js, backbone and Node. I am currently responsible for SharePoint Infrastructure set up and leading teams in various medium and large scale projects, architecting, designing & installing SharePoint farms, developing custom components,, and providing advanced SharePoint administration and development training to teams and customers. I regularly speaks in various SharePoint User Groups and other Events. I have MCSA Windows Azure, MCSA Office 365, MCSE & MCSD SharePoint 2013, Microsoft Certified Developer (MCD) and holds MCPD, MCTIP and MCTS for SharePoint 2010, MCTS MOSS 2007 & WSS 3.0, MCPD, MCITP (EPM 2010 & 2007) and MCSD .NET.
This entry was posted in General Interest. Bookmark the permalink.

Leave a Reply

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