Wednesday, 22 June 2016

Map Term Set to Site Column on SharePoint using CSOM PowerShell

We will see how to map SharePoint taxonomy term set to a Site column using CSOM with PoweShell on SharePoint 2013 / SharePoint 2016 / SharePoint Online sites.

The basic idea of the article is to show how we can automate the mapping process of term set to site columns.

Steps Involved:

The following prerequisites need to be executed before going for any operations using CSOM PowerShell on SharePoint sites. 
  1. Add the references using the Add-Type command with necessary reference paths. The necessary references are Microsoft.SharePoint.Client.dll, Microsoft.SharePoint.Client.Runtime.dll and Taxonomy dll.
    1. Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"  
    2. Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"  
    3. Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll"  
  2. Initialize client context object with the site URL.
    1. $siteURL = ""  
    2. $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)  
  3. If you are trying to access SharePoint Online site then you need to setup the site credentials with credentials parameter and load it to the client context.
    1. #Not required for on premise site - Start    
    2. $userId = ""    
    3. $pwd = Read-Host -Prompt "Enter password" -AsSecureString    
    4. $creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userId, $pwd)    
    5. $ctx.credentials = $creds    
    6. #Not required for on premise site - End    
  4. If you are trying to access the SharePoint on premise site then the credentials parameter is not required to be set to the context but you need to run the code on the respective SharePoint Server or you need to pass the network credentials and set the context.
    1. #Credentials for on premise site - Start    
    2. $pwd = Read-Host -Prompt "Enter password" -AsSecureString    
    3. $creds = New-Object System.Net.NetworkCredential("domain\userid", $pwd)    
    4. $ctx.Credentials = $creds    
    5. #Credentials for on premise site - End    
Before executing below steps, the site column’s Term Setting will look like the image below.

Now we will see how we can retrieve term sets from the term store and assign it to the site column.

Retrieve Term Sets:

The below logic retrieves term set called "Test" from the taxonomy term store. 
  1. Get taxonomy session object by loading and executing the context.
    1. $taxStore = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($ctx)  
    2. $ctx.Load($taxStore)  
    3. $ctx.ExecuteQuery()  
  2. Get the term store by using term store name and term store collection object.
    1. # Retrieve Term Stores & Groups  
    2. $termStores = $taxStore.TermStores.GetByName("Managed Metadata Service")  
    3. $ctx.Load($termStores)  
    4. $ctx.ExecuteQuery()  
    5. $termStore = $termStores[0]  
    6. $Groups = $termStore.Groups  
    7. $ctx.Load($termStore)  
    8. $ctx.Load($Groups)  
    9. $ctx.ExecuteQuery()  
  3. Get the appropriate group where term sets are available by using group name and group collection object. From the selected group, select the term set from the term set collection and term set name.
    1. # Retrieve Term Set & Update Site Column with TermSet  
    2. $Group = $Groups.GetByName("Testing")  
    3. $termSet = $Group.TermSets.GetByName("Test")  
    4. $ctx.Load($termSet)  
    5. $ctx.ExecuteQuery()  
We got the term set. Now we will see how we can map it to site column called "Test".

Mapping Term Set to Site Column:
  1. From the context, get the root web object. Then get the fields. From the field collection, get the respective field with the field name.
    1. $web = $ctx.Site.RootWeb  
    2. $field = $web.Fields.GetByTitle("Test")  
  2. We need to cast the field object to taxonomy field by invoking generic methods. For this we will use MakeGenericMethod along with GetMethod. Here we will use Taxonomy Field object for casting field object.
    1. $field = [Microsoft.SharePoint.Client.ClientContext].GetMethod("CastTo").MakeGenericMethod([Microsoft.SharePoint.Client.Taxonomy.TaxonomyField]).Invoke($ctx, $field)  
  3. Then we can assign the term set and store id of the term set identified from the above section to the field by following code snippet.
    1. $field.SspId = $termStore.Id   
    2. $field.TermSetId = $termSet.Id   
  4. Then update field, load objects and execute the query to complete processing.
    1. $field.Update()  
    2. $ctx.Load($web)  
    3. $ctx.Load($field)  
    4. $ctx.ExecuteQuery()  
Here we have mapped the term set to corresponding site column. The below image shows the term set mapping to site column.

The above set of operations will help in mapping the term set of taxonomy to managed metadata site column. But this will not affect the columns already created at list level using the above site column. For updating the list level metadata columns with the same changes, we need to explicitly use an update operation, where it will push the changes from site level to list levels. Instead of giving $field.update() in the above code, we need to give $field.UpdateAndPushChanges($true). This will make changes available for list columns already created.