Tag Archives: Bug

Managed Metadata columns fail to sync between SharePoint and client applications

This issue seems to be cropping up a lot at the moment, one possible fix is below.

Symptoms:

When you set a Managed Metadata Service (MMS) column in SharePoint these values are pushed down to the office document and will be visible on the Document Information Panel (DIP). When these values are changed in an office document however these MMS column changes are not updated in the SharePoint item. Non MMS fields (i.e. Single Line of Text, Choice, Number etc.) are correctly synced. If you close and re-open the office document, even from another computer, any changes made in office to the MMS values will still remain as you set them in the DIP. However as normal any changes to the values in SharePoint will be pushed down to the office document overwriting any values in the DIP.

In summary: SharePoint can write to the office document but MMS values in the document cannot be written to SharePoint by office.

Note: If text, choice or other non MMS fields are not being synced when you save the document then this is probably unrelated to your issue.

Where has this been seen:

We’ve seen it in at least two SharePoint 2010 SP1¬†environments in the last week, with farms using varying CUs. No obvious cause has been identified.
The main example is in office, at least word and Excel. This has also been seen with Harmon.ie where it is impossible to set the MMS value, it is probable other systems may be effected.

Solution:

Add and remove a MMS column from each list. You can confirm that this fixes your issue by performing a manual update of a single list and then run a bulk correction using PowerShell. Note that you will need to test and re-create any faulty Site Templates.

Cause

Not known at this time, it appears to be related to the document parser. It appears that in some cases the document Parser process fails on MMS values. The value in Word is maintained in the document’s xml fields but is not correctly udpated (at least in our tests) with the correct namespace for the term or termID.
It seems that by adding a new MMS column the issues with the other columns is corrected, we believe this might be due to some version or synchronisation process but have not tracked down the root cause.

Manual steps

In your list or library, open the list settings.

Image of library ribbon with Library Settings highlighted

Library Settings

Click on ‘Create Column’

Image of Create Column highlighted within Library Settings

Create Column

Enter a name, here we will use ‘DummyColumn’ and select ‘Managed Metadata’

Column creation process with Name and Type highlighted

Create Column (specify type and name)

Select a value in the MMS

Image of Managed metadata value selected in column creation

Select Managed Metadata Value

Click OK.

At this point you should be able to confirm that the MMS field is now synchronised between Office and SharePoint. You can then delete the column.

Note: If the process fails then delete the column anyway, unless you’re selling childrens accessories then it will probably be of little use.

Programatic

This can be scritped in several ways but the primary method will be on server PowerShell. An example script is shown below:

<#
Author: Alex Brassington (Trinity Expert Systems)
Date: 26/04/2013
Description:
Adds and removes an MMS colummn to every library in the white list for all sites in a web application. This is to
fix the office => SharePoint managed metadata service sync field issues.
This can be run with either a white list of lists/libraries to update or without, in which case all document libraries will be updated. It is possible that this only needs to run on one document library per site but i have not yet been able to confirm or refute that.
#>

Add-PSSnapin Microsoft.SharePoint.PowerShell -ea SilentlyContinue

#Reference to the content type hub to be used for the MMS Column    
$CTHubURL= "http://sharepoint/sites/cthub"

#Site Collection to modify
$SCURL = "http://sharepoint/sites/cthub"

#Name of the MMS instance to use
$MMSInstance = "Managed Metadata Service"


#A 'white list' of libraries to process. Note that this currently contains 'DOcuments' which should be handled as a special case.
$librariesToCheck =
(
    "Documents",
    "Entertainment",
    "Project Documents",
    "Management Information"
)

    #Setup the termstore object
    $contentTypeHub = Get-SPSite $contentTypeHubURL
    $session = New-Object Microsoft.SharePoint.Taxonomy.TaxonomySession($contentTypeHub)
    $termStore = $session.TermStores | ? {$_.Name -eq $MMSInstance}
    $group = $termStore.Groups["Demo Terms"]
    $termSet = $group.Termsets["Condiments"]


Function Update-LibrariesInSiteCollection ()
{
[CmdletBinding()]
    Param (
    [Parameter(Position=0,Mandatory=$true,ValueFromPipeLine=$true)][string]$siteURL, 
    [Parameter(Position=1,Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSet]$termSet,
    [Parameter(Position=2,Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermStore]$termStore,
    [Parameter(Position=3,Mandatory=$false)][string]$errorFile,
    [Parameter(Position=4,Mandatory=$false)][string[]]$librariesToCheck
    )
    
    
    #No change required, only used internally
    $columnName = "TempColumn"
    
    #Get the SharePoint Site Collection to process
    $site = Get-SPSite $siteURL
    Write-Verbose "Updating Site Collection $($site.URL)"
    foreach ($web in $site.AllWebs)
    {
        Write-Verbose "Updating Web $($web.URL)"
        
        #If there's a list of folders to use as a whitelist then use them
        if ($librariesToCheck)
        {
            Write-Verbose "Updating libraries based on provided White list"
            $lists = $web.Lists | ? {$librariesToCheck -contains $_}
        }
        else
        {
            #If not then process all libraries.
            Write-Verbose "Updating all document libraries only"
            $lists = $web.Lists | ? {$_.BaseType -eq "DocumentLibrary"}
        }
        
        foreach ($list in $lists)
        {
            Write-Verbose "Updating list $($list.Title)"
            try
            {
                #Create a new taxonomy field
                $taxField = $list.fields.CreateNewField("TaxonomyFieldType", $columnName)
                
                #set the term store ID and the termset ID 
                $taxField.SspId = $termStore.Id
                $taxField.TermSetId = $termSet.Id
                
                #Add the column to the list
                $list.Fields.Add($taxField) | Out-Null
                $list.Update()
                
                #Remove the column
                $column = $list.fields[$columnName]
                $column.Delete()
                Write-Verbose "List Complete $($list.Title)"
            }
            catch
            {
                Write-Error "Error encountered on List: $($list.Title)"
            }
        }
    $web.Dispose()
    }
    
    #If a file path was given then write out the error log.
    if ($errorFile)
    {
        $error >> $errorFile
    }
    #Dispose of the site collection
    $site.Dispose()
}

Update-LibrariesInSiteCollection -siteURL $SCURL -termSet $termSet -termStore $termStore -errorFile $ErrorPath -Verbose

My thanks to my colleague Paul Hunt (aka Cimares) who found the fix that we scripted above.