Working with managed metadata and default colulmn values with PowerShell

Posted Wednesday, July 31, 2013 8:35 PM by CoreyRoth

Quite some time ago, I wrote about how to set default column values using C#.  However, I find it useful to work with them using PowerShell quite often.  The reason being, I often use this as a utility to work set default column values on document libraries or folders in bulk.  I often do this as an exercise of adding metadata to document libraries that didn’t have it previously.  I was doing this recently for a client and I wanted to make use of managed metadata columns and found that setting a default column value of this type is not straight forward.  This is no surprise though, since anytime you deal with managed metadata columns, nothing is as it seems.  Let me show you what you need to know.

Start a new PowerShell script file (.ps1).  The first thing we need to do is add some assemblies for referencing both the term store and the default column values.

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Taxonomy")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.DocumentManagement")

To do this, we first need to get a reference to the actual term object.  We need this because of the way we set the default column value.  To do this we’re going to need a site collection object as well.  We can do this with standard PowerShell commands.  Specify the entire path to the subsite that you need because we are just going to use SPSite.OpenWeb() to get our SP-Web object for later.

$site = Get-SPSite http://server/sitecollection

Take a look at my term set as we’ll use the values here in our PowerShell commands to get the term we want.  In this case, we are going to use the selected term, Invoice.

PowerShellTermStore

I am going to then issue the following statements to get the term. 

$session = New-Object Microsoft.SharePoint.Taxonomy.TaxonomySession($site)
$termStore = $session.TermStores[0]
$group = $termStore.Groups["Classification"]
$termSet = $group.TermSets["Document Types"]
$terms = $termSet.GetAllTerms()
$term = $terms | ?{$_.Name –eq “Invoice”}

First, we need to get a new TaxonomySession using the SPSite object we got earlier.  We then open the default term store using an indexer of 0.  Once we have a TermStore object, we can get the group we need, Classification.  Then we get the Document Types TermSet using an indexer.  At this point, we can call GetAllTerms() to return all terms in the term set.  Note, that this can be an expensive operation, but we really have no choice.  Lastly, we use a standard PowerShell technique to compare the list of terms and select one by name.  That leaves us with the Term object we need.

One we have the term we need, we need to get a reference to the document library on the site we are working with.  Start by getting an SPWeb object.

$web = $site.OpenWeb()

Now, we are just going to get the list we need by name using an indexer.

$list = $web.Lists["Documents"]

At this point, we are ready to set our default column values.  This code will actually look similar to my previous blog post.  Start by getting a MetadataDefaults object.  You’ll need to pass in the SPList object we just created.

$columnDefaults = New-Object Microsoft.Office.DocumentManagement.MetadataDefaults($list)

Now we use the SetFieldDefault() method to create our defaults.  It requires a SPFolder object, the internal name of the SPField (not display name), and the value itself.  If we were working with a Single line of text field, it would look something like this.

$columnDefaults.SetFieldDefault($list.RootFolder, "MyTextField", “MyTextValue”)

However, we are working with Managed Metadata, so if you try to assign the value like that, you’ll get the following error message.

The given value for a taxonomy field was not formatted in the required <int>;#<label>|<guid> format.

If you are not familiar with that format, let me explain.  The first value is the LCID code.  A lot of you use English so likely a value of 1033 will work.  If that isn’t your default language, you probably know your LCID code or you can go look it up.  Then, the value it expects for <label> is the text value of the term, for that we just use $term.Name.  Lastly, we need the GUID of the term, so for that we use $term.Id.  This gives us a command that looks like this.

$columnDefaults.SetFieldDefault($list.RootFolder, "MyManagedMetadataField", "1033;#" + $term.Name + "|" + $term.Id)

Finally, with any SharePoint construct, we need to call Update() to commit our changes.

$columnDefaults.Update();

If you got everything correct, that should work for you.  You’ll want to add you error handling of course, but hopefully, this is enough to get you started.

Comments

# Working with managed metadata and default colul...

Sunday, August 4, 2013 12:17 PM by Working with managed metadata and default colul...

Pingback from  Working with managed metadata and default colul...

# re: Working with managed metadata and default colulmn values with PowerShell

Thursday, October 16, 2014 11:57 AM by Andy McHargue

I have a list where I can see the default value in Default Column Values, but when I run

$metadataDefaults = New-Object -TypeName Microsoft.Office.DocumentManagement.MetadataDefaults $list

$metadataDefaults.GetDefaultMetadata($list.RootFolder)

I get nothing. This works fine for another list in the same site collection. Any ideas?

Also, when I am able to inspect the default by GetDefaultMetadata($list.RootFolder), the first number is not 1033 as in your example. It's generally a number like 1 or 2.

# re: Working with managed metadata and default colulmn values with PowerShell

Tuesday, November 18, 2014 3:51 AM by Sam Josupeit

Hi Corey!

First of all i want to thank you for your great post! It helped me save lots of time, for this topic is everything else than pretty much explain by microsoft.

In addition to Andy's comments, i'd like to say, that the number you use as a language-ID should be more like a serial number of the item from the termset.

And btw., for those who where looking for:

when getting a column default value, like Andy mentioned, via

$defMetadata = GetDefaultMetadata($someListFolder),

you will get a System.Web.UI.Pair-object, which is explained in the technet for use in C# but not in PowerShell.

When getting this Pair-Object, which i call mis-usefully declared, it is more an Array.List and you can get the separate Values by e.g. calling

$defMetadata[0].First and $defMetadata[0].Second

This should be useful for copying column default values from an listfolder to an other an in another list.

B.R.

Sam

# re: Working with managed metadata and default colulmn values with PowerShell

Tuesday, April 28, 2015 3:02 AM by Alex Klein

Hi Corey!

Thank you for the great tutorial! The default values are getting assigned to the documents in the folder, or at least you can see the default values set under "Default Column Value Settings".

However if you upload a new document via Drag&Drop or "Upload a document" then the managed metadata fields remain empty/unfilled. It turns out, that these default values need to be kind of "confirmed" in the UI - so you should choose the default value setting and click "OK", which is not so optimal and makes the automatic approach useless. Would you probably have a solution for this incorrect behavior?

Leave a Comment

(required)
(required)
(optional)
(required)