"Knowledge has to be improved, challenged, and increased constantly, or it vanishes."

Backup and Restore Site Collection with Managed Navigation

Managed navigation in SharePoint allows you to define SEO friendly URLs to SharePoint pages. This feature helps your visitors remember the URLs and also increases your page ranking in search engines. Once you enable the managed navigation for your site, SharePoint relates every page with a navigation term. To understand more about managed navigation, find the MSDN link

https://msdn.microsoft.com/en-us/library/office/jj163978.aspx

In this article, I am going to explain how you can restore site collections that uses managed navigation from one farm to different farm. This is important as when you are working on a project you need to deal with several environments. You will have a development environment where your team actually work on, a testing environment where users ensure the functionality/content is right before showing to customer, a staging environment where the customer checks the site before going live and finally a production environment. It is obvious that you need to move site from one environment to another frequently, probably in the below order.

development -> test -> staging -> production

Assumptions

For the purpose of this article, I am assuming you have two SharePoint 2016 farms namely source farm and destination farm. You have a site collection available in the source farm with managed navigation.

I also assume you already restored site collection in the destination farm. Backup/Restore of site collections is not the topic of this article, however if you wish to read more about backup/restore in SharePoint, refer my article

https://weblogs.asp.net/sreejukg/backup-and-restore-in-sharepoint-2010-using-powershell

To visualize the scenario where we are going to start from, refer the below image.

clip_image002

Step 1 : Backup the MMS Database from the source farm

First thing you need to do is to take a backup of your managed navigation instance database from the source farm. From the source farm, open SharePoint management shell. First get the the GUID of the managed meta data service instance. Execute the following PowerShell command

Get-SPServiceInstance

See the output of the command in my test environment.

clip_image004

In order to take the backup of your meta data service database, you need to stop the service instance of your managed meta data service. To stop your managed meta data service instance, execute the following command, make sure to use the GUID from your environment.

Stop-SPServiceInstance -Identity a6325294-0c81-4dde-b4ba-f55c90e6b4c0

See the output of the command, you need to Press Y to confirm.

clip_image006

Ensure that the service instance status is disabled. You can use Get-SPServiceInstance command and ensure the service is disabled.

Once the metadata service is stopped, you can detach the database and copy the mdf & ldf files of your database. By default, you will be able to locate the meta data service instance from the SQL Server management studio by the name of the database. If you have many databases, you can use the following command to find out the meta data service application database.

Get-SPDatabase | Where {$_.Type -like "*MetadataWebService*"} | Select Name

See the output of the command as below.

clip_image008

Now open SQL Server management studio, and expand the databases node and locate your managed metadata service database.

clip_image010

Right click the instance database and select tasks –> Detach


clip_image012

Click OK. Now you can copy the mdf /ldf files of your database from the data directory.

clip_image013

Once you copy the database files and keep it in a separate location, you need to use attach database command to attach the database back to your source farm. From the management studio, right click the databases node and select attach database, and then select the mdf file you detached just now. Once the database is attached, you need to start the service instance. Use the below command to start the meta data service instance, make sure you use GUID from your environment.

Start-SPServiceInstance -Identity bd7f2678-4569-472b-90a5-a11b44bd9e68

With this you have done the steps in the source server.

Step 2: Restore Metadata database to the destination farm

You need to copy the mdf & ldf files to the destination database server, ideally in the data folder of your destination server.

In the SQL Server Management Studio of the destination farm, Right click the databases node, and select Attach

clip_image015

In the attach databases dialog, select the mdf file you copied from the source farm.

clip_image016

Note: You can rename the file names or database name as you wish, for the purpose of this demonstration, I renamed the attached database to “MMS_DB”

clip_image018

Step 3: Set the restored databases as the metadata service application database in the destination farm

Now you need to set the metadata service application database in the destination farm to the newly restored database. Open SharePoint Command Shell in the destination farm execute the following command.

$app = Get-SPServiceApplication -Name "Managed Metadata Service"

Set-SPMetadataServiceApplication -Identity $app -DatabaseName "MMS_DB"

Note: In the above command you need the name your metadata service application. The following power shell script will help you find the service application names of all service applications.

Get-SPServiceApplication | Select Name

Once you set the database, you may want to ensure whether the database is updated. Run the below PowerShell scripts so that you will get the database name.

$app = Get-SPServiceApplication -Name "Managed Metadata Service"

$app | Select Database

Let us recollect what we have done so far, we restored the MMS database to the destination farm and set it as the service application database.

Step 4: Associate Site Collection and Sites to Term Store

The restored database contains the term set and terms from the source site collection. The terms are associated to pages and the term set is associated to the site collection. The association is maintained by using the ids of site collection and terms/termsets. But when you restore the site collection, the restored site collection will have a new ID and now all the associations are broken. We need to re-associate sites and subsites to the term store.

In order to associate, you need to find the term set you were using. Open the restored database in SQL Server management studio, open new query window and execute the following query.

select * from ecmgroup

clip_image020

You need to copy the UniqueId of the term set of your site collection.

Let me explain how a site collection or sub site is associated with the term set. The site collection rootWeb has a property as below.

SiteCollectionGroupId<TermStoreID>

The <TermStoreID> is the id of the default site collection term store. The value of the property will be the uniqueID you found from the previous SQL Query.

e.g.

Property Name

Value

SiteCollectionGroupId42c2d963-0fda-48ac-9762-49206d171a13

E063ACFA-1A83-4E6E-82DF-66C36459016A

Once you add the property, you need to use the AddSiteCollectionAccess Method of the term store group to grant the permission for the site collection to the group.

The below PowerShell script will do this, you need to use the uniqueID from the SQL query as the groupID and your site URL.

#Function definition to associate the termstore to site Collection
function AssociateSiteCollectionToTermStore($site, $groupId)
{
    $tx = New-Object Microsoft.SharePoint.Taxonomy.TaxonomySession($site)
    $termstore =$tx.DefaultSiteCollectionTermStore
    $termStoreId = $termstore.Id
    $SiteCollectionTermStorePropertyName = "SiteCollectionGroupId" + $termStoreId
    $web = $site.RootWeb
    $webProp = $web.GetProperty($SiteCollectionTermStorePropertyName)
    If ($webProp –eq $null)
    {
        $web.AddProperty($SiteCollectionTermStorePropertyName , $groupId )
    }
    Else
    {
        # Property exists – remove/re-add the property
        $web.DeleteProperty($SiteCollectionTermStorePropertyName)
        $web.AddProperty($SiteCollectionTermStorePropertyName , $groupId )
    }
    $web.Update()
    $group = $termstore.Groups | Where-Object {$_.id –eq $groupId}
    $group.AddSiteCollectionAccess($site.id)
    $termstore.CommitAll()
}
$site = Get-SPSite <Your Site URL>
$groupId = "E063ACFA-1A83-4E6E-82DF-66C36459016A" #The UniqueId from the SQL query
AssociateSiteCollectionToTermStore $site $groupId

Step 5: Associate Site Collection and Sites to Term Store

Now if you go to the term store, you will find the terms, but still you will find the friendly URLs will not work!. You need to update the permissions! Now the terms owner is owned by the source farm user. Typically your different environments are under different active directory, so you need to modify the owner of each term.

The below PowerShell script will help you to set the owner of all termset in the termstore.

#Update Owner function
function UpdateTermOwner($site, $newOwner, $groupId)
{
    $tx = New-Object Microsoft.SharePoint.Taxonomy.TaxonomySession($site)
    $termstore =$tx.DefaultSiteCollectionTermStore
    foreach($admin in $termstore.TermStoreAdministrators)
    {
        #Delete the existing owner first
        Write-Host ([String]::Format("Removing User {0} from TermStore Administrators",$admin.PrincipalName)) -foregroundcolor blue
        $termStore.DeleteTermStoreAdministrator($admin.PrincipalName);
    }
    #Adding new term Store Administrator
    Write-Host ([String]::Format("Adding User {0} as TermStore Administrator",$newOwner)) -foregroundcolor green
    #$termStore.AddTermStoreAdministrator($newOwner);
    $group = $termstore.Groups | Where-Object {$_.id –eq $groupId}
    foreach($termSet in $group.TermSets)
    {
        Write-Host ([String]::Format("Adding User {0} as Owner",$newOwner)) -foregroundcolor green
        #$termSet.Owner = $newOwner
    }
    $termStore.CommitAll();
}
$site = Get-SPSite <Your Site URL>
$newOwner = "Domain\user"
$groupId = "E063ACFA-1A83-4E6E-82DF-66C36459016A"
UpdateTermOwner $site $newOwner $groupId

Step 6: Update the Navigation Source to Taxonomy Provider for all your Sites

After completing the step 5, I was in the impression that the terms must be mapped to the sites correctly. But the friendly URLs were note working yet, I found if I got to any site and just modify the navigation property and save it, the friendly URLs starts working. So, you need to traverse through all your sub sites and update your navigation. The below PowerShell Script just perform this.

Now you have access to the terms. You need to update the navigation

# Fix the Navitation
function FixNavigation($url)
{
    try
    {
        $web = Get-SPWeb $url;
        Write-Host ([String]::Format("Procesing web {0}",$web.Url)) -foregroundcolor White
        WebNavSettings = New-Object Microsoft.SharePoint.Publishing.Navigation.WebNavigationSettings($Web);
        $WebNavSettings.GlobalNavigation.Source = "PortalProvider"
        $WebNavSettings.CurrentNavigation.Source = "PortalProvider"
        $WebNavSettings.Update()
        Write-Host ([String]::Format("Updated navigation to Structured {0}",$web.Url)) -foregroundcolor blue
        $web = Get-SPWeb $url;
        $WebNavSettings = New-Object Microsoft.SharePoint.Publishing.Navigation.WebNavigationSettings($Web);
        $WebNavSettings.GlobalNavigation.Source = "TaxonomyProvider"
        $WebNavSettings.CurrentNavigation.Source = "TaxonomyProvider"
        $WebNavSettings.Update()
        Write-Host ([String]::Format("Updated navigation to Structured {0}",$web.Url)) -foregroundcolor green
        if($web.Webs.Count -gt 0)
        {
            foreach($subWeb in $web.Webs)
           {
                #$web.Url
                FixNavigation $subWeb.Url;
            }
        }
    }
    catch
    {
        Write-Host ([String]::Format("Error processing web at $url, with Exception: {0}",   $_.Exception.Message)) -foregroundcolor Red
    }
}
$url = <Your Site URL>
FixNavigation($url)

Summary

I tested these steps in couple of environments and it worked. Use the comment area below to post your experience. Enjoy!

7 Comments

Add a Comment

As it will appear on the website

Not displayed

Your website