Sync TaxonomyHiddenList after updating Term value programmatically for SharePoint 2013/2016

In one of my project, there was a requirement to manually update term set title and see the updated version in library view. When I did that it didn’t reflect the change on demand. So let me share my experience with the below scenario:

I have one library where I have added a custom field of type managed metadata type.

Columns

These fields (Regions, Survey Title) are targeting to its related TermSet from the Term Store and showing it on the library view.

When I added a new item to the library, I selected it’s metadata and saved the document.

Now I had change request to update metadata term’s title. Let’s consider Region has one value “Colorado” and change request was to change it to “CO”.

To achieve this, I first updated the term title in the term store manager but change wasn’t reflected immediately.

Below are the different ways to achieve the changes immediately:

Out of the Box way:

There is a Timer job for this, it actually sync the term store data to the hidden taxonomy list for that site collection and update wherever term fields are used.

Though to run this job manually, below are steps I followed:

  • Go to the Central Administration > Monitoring > Job DefinitionsTaxonomy Update Scheduler (for your web application). Open it.
  • By default that Job will run hourly, so to run it manually you have to click on Run Now.
  • Once Job is successful, Data from term store will be synced to the TaxonomyHiddenList for that site collection and I was able to see the updated metadata field title for the CO in place of Colorado.

Programmatically with PowerShell:

This could also be done by PowerShell, Below is the snippet I used:

$siteUrl = "http://mysharepoint:1327/"
$site = Get-SPSite $siteUrl
[Microsoft.SharePoint.Taxonomy.TaxonomySession]::SyncHiddenList($site)
$site.dispose()

Programatically with C# SharePoint Console Application:

Similar way you can achieve the same with Server side object model. Following code snippet by creating simple console application and run where SharePoint is installed. Below was the snippet I used:

using Microsoft.SharePoint;
using Microsoft.SharePoint.Taxonomy;
using System;

namespace TaxonomyUpdater
{
    public static class TaxonomyHiddenList
    {
        public static void Update(string SiteUrl)
        {
            SPSite Site2Update = new SPSite(SiteUrl);
            TaxonomySession.SyncHiddenList(Site2Update);
            Site2Update.Dispose();
        }
    }
}

Additional Problem:

There was a situation where I wasn’t able to update the termset data by any of the above solution, from this blog post: Taxonomy Update Scheduler not working? I was able to figure out there was a table in the MMS database called ECMUsedTerm. This table wasn’t updated with all the terms data in it. This could be caused by two different scenarios:

  1. If we recreated the Managed Metadata Service with a clean database, importing the terms with the same id’s then of course the ECMUsedTerm table is empty / information is lost.
  2. If we moved the content database from one farm to another (maybe from staging to prod) which of course has a new Managed Metadata Service, then the ECMUsedTerm table is of course not in sync.

Solution:

To solve this issue, from the article referred I found the below PowerShell code, which will sync the ECMUsedTerm data.

$url = "https://yoursite"
$site = Get-SPSite $url
$tax = Get-SPTaxonomySession -Site $url
$ts = $tax.TermStores[0]
$ts.UpdateUsedTermsOnSite($site)
$site.dispose()

By using this snippet, I was able to update the records in the ECMUsedTerm table of MMS database and now my term set was reflecting once any of the above solution or timer job is ran successfully.

Happy SharePointing!!

Advertisements

Restore Site Collection with new Content database to existing web application.

In one of my project, I had requirement to migrate record center site collection to the new server but in that requirement I had to create only new site collection with existing web application and different database.

So to achieve this, below is the detailed snippet of PowerShell script.

First of all I took backup of the source site collection:

Backup-SPSite –Identity http://sharepointolddev –LiteralPath "C:\Backup\olddev.bak"

Now to restore above backup into new site collection I needed to create separate content database. Below is the script to create new content database under a web application.

New-SPContentDatabase -Name "WSS_Content_DBNew" -DatabaseServer "MYDBNAME"  -WebApplication http://sharepointdev/

Once that Database is created I created empty site collection with record center site template. Below is the snippet to create new site collection with created content database.

$site = "http://sharepointdev/sites/newdev"
$dbname = Get-SPContentDatabase "WSS_Content_DBNew"
$ownerAlias = "sp\prathod";
New-SPSite -URL $site -OwnerAlias $ownerAlias -SecondaryOwnerAlias $ownerAlias -ContentDatabase $dbname -Template "OFFILE#1"

Once site collection is created I simply restored existing site collection backup with below snippet:

Restore-SPSite –Force –Identity http://sharepointdev –LiteralPath "C:\Backup\olddev.bak"

That’s it, site collection is restored with new content database in existing web application.

Powershell List Operations

Various Powershell List Operations of SharePoint :

#### Create Document Library ####
$spWeb = Get-SPWeb -Identity http://sharepoint/ 
$listTemplate = [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary 
$spWeb.Lists.Add("My Custom Library","My Custom Library Description",$listTemplate)

#### Add Folder To Library ####
$spDocumentLibrary = $spWeb.GetList("My Custom Library")
$spFolder = $spDocumentLibrary.AddItem("",[Microsoft.SharePoint.SPFileSystemObjectType]::Folder,"My New Folder")
$spFolder.Update()

#### Allow adding Content type to Library - Enable Content Type ####
$spDocumentLibrary.ContentTypesEnabled = $true

#### Add New Content Type to Library ####
$newCTtoAdd1 = $spWeb.ContentTypes["Content Type Name"]
$newCT1 = $spDocumentLibrary.ContentTypes.Add($newCTtoAdd1)

#### Remove Content Type from Library ####
$oldCTtoRemove = $spDocumentLibrary.ContentTypes["Document"]
$spDocumentLibrary.ContentTypes.Delete($oldCTtoRemove.Id)
$spDocumentLibrary.Update()