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.
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.