Thursday, September 25, 2014

Create managed metadata term sets via Sharepoint client object model in Sharepoint Online

During provisioning to Sharepoint Online we usually try to automate as much actions as possible. One of such actions is creation of managed metadata hierarchy (Group > Term sets > Terms). In on-premise installation with full access to the basic object model this is straightforward process nowdays, but in Sharepoint Online we need to use client object model instead. Before to start you should ensure that account under which code will run is added to Term store administrators group (in order to check it on the root site of your site collection go to Site settings > Term store management). Also we will need xml file with initial managed metadata hierarchy in the following format:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <Group Name="MyGroup" Id="{C16C65EA-446B-45F3-B232-FA4212C8E621}">
   3:   <TermSet Name="TermSet1" Id="{D4ABDBD7-9E60-4493-9A09-F90AB06B812E}">
   4:     <Term Name="Item11" />
   5:     <Term Name="Item12" />
   6:     <Term Name="Item13" />
   7:   </TermSet>
   8:   <TermSet Name="TermSet2" Id="{30BE6983-F40C-4D96-8413-10BDB920D31B}">
   9:     <Term Name="Item21" />
  10:     <Term Name="Item22" />
  11:     <Term Name="Item23" />
  12:   </TermSet>
  13:   <TermSet Name="TermSet3" Id="{AD589539-8875-4E8E-BAAE-C0223E3B0124}">
  14:     <Term Name="Item31">
  15:       <Term Name="SubItem1" />
  16:       <Term Name="SubItem2" />
  17:       <Term Name="SubItem3" />
  18:     </Term>
  19:     <Term Name="Item32" />
  20:     <Term Name="Item33" />
  21:   </TermSet>
  22: </Group>

As shown in the example above ids for groups and term sets are explicitly specified. They will be needed for binding managed metadata fields – I will write about it in another article. Also in this example only 2 levels of nested terms are shown, but you may use any nesting level, just ensure that xml if formatted correctly.

PowerShell script which creates taxonomy hierarchy from the xml file in the local site collection term store is shown below:

   1: function Create-Term($ctx, $parent, $termXml, $lcid)
   2: {
   3:     Write-Host "Create term" $termXml.Name -foregroundcolor green
   4:     $term = $parent.CreateTerm($termXml.Name, $lcid, [System.Guid]::NewGuid())
   5:     $ctx.ExecuteQuery()
   6:  
   7:     if ($termXml.Term)
   8:     {
   9:         $termXml.Term | ForEach-Object { Create-Term $ctx $term $_ $lcid }
  10:     }
  11: }
  12:  
  13: function Create-TermSet($ctx, $group, $termSetXml, $lcid)
  14: {
  15:     Write-Host "Creating term set" $termSetXml.Name -foregroundcolor Green
  16:     $termSet = $group.CreateTermSet($termSetXml.Name, $termSetXml.Id, $lcid)
  17:     $ctx.ExecuteQuery()
  18:  
  19:     $termSetXml.Term | ForEach-Object { Create-Term $ctx $termSet $_ $lcid }
  20: }
  21:  
  22: function Get-TermStore($ctx)
  23: {
  24:     Write-Host "Loading taxonomy session" -foregroundcolor Green
  25:     $session =
  26: [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($ctx)
  27:     $session.UpdateCache();
  28:     $ctx.Load($session)
  29:     $ctx.ExecuteQuery()
  30:  
  31:     Write-Host "Loading term stores" -foregroundcolor Green
  32:     $termStores = $session.TermStores
  33:     $ctx.Load($termStores)
  34:     $ctx.ExecuteQuery()
  35:     $termStore = $termStores[0]
  36:     $ctx.Load($termStore)
  37:     Write-Host "Term store with the following id is loaded:" $termStore.Id
  38: -foregroundcolor Green
  39:     return $termStore
  40: }
  41:  
  42: function Provision-TermSets($ctx, $xmlFilePath)
  43: {
  44:     Write-Host "Load term sets from xml" -foregroundcolor Green
  45:     [xml]$xmlContent = (Get-Content $xmlFilePath)
  46:     if (-not $xmlContent)
  47:     {
  48:         Write-Host "Xml was not loaded successfully. Term sets won't be created"
  49: -foregroundcolor Red
  50:         return
  51:     }
  52:  
  53:     $termStore = Get-TermStore $ctx
  54:  
  55:     Write-Host "Creating group" $xmlContent.Id -foregroundcolor Green
  56:     $groups = $termStore.Groups
  57:     $ctx.Load($groups)
  58:     $ctx.ExecuteQuery()
  59:  
  60:     $group = $groups | Where-Object {$_.Name -eq $xmlContent.Group.Name}
  61:     if ($group)
  62:     {
  63:         Write-Host "Group" $xmlContent.Group.Name "already exists"
  64: -foregroundcolor Yellow
  65:         return
  66:     }
  67:  
  68:     $group = $termStore.CreateGroup($xmlContent.Group.Name, $xmlContent.Group.Id)
  69:     $ctx.ExecuteQuery()
  70:     $xmlContent.Group.TermSet | ForEach-Object {
  71: Create-TermSet $ctx $group $_ $termStore.DefaultLanguage }
  72: }

It is quite self-descriptive: at first it creates group, then for each term set xml tag creates appropriate term set and then terms with sub terms. Function Provision-TermSets is called this way:

   1: $ctx = New-Object Microsoft.SharePoint.Client.ClientContext("http://example.com")
   2: $ctx.AuthenticationMode =
   3:     [Microsoft.SharePoint.Client.ClientAuthenticationMode]::Default
   4: $securePassword = ConvertTo-SecureString "password" -AsPlainText -Force
   5: $credentials =
   6:     New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials(
   7:         "username", $securePassword)
   8: $ctx.Credentials = $credentials
   9:  
  10: Provision-TermSets $ctx "c:/temp/termsets.xml"

After executing go to Site settings > Term store management and check that your managed metadata hierarchy is successfully created.

No comments:

Post a Comment