Move , Merge and Rename operations on Managed Metadata Term using powershell
Managed metadata is a hierarchical collection of centrally managed terms that you can define and then use as attributes for items in Microsoft SharePoint Server 2010. There may be scenario when you need to move terms in hierarchy or merger terms or may need to rename the term. All the operations mentioned can be easily done manually using Out of Box feature. Consider a scenario where you need to move say 50 terms or say need to perform merge operation on large number of terms, in this case doing these operation manually would take time.
To perform these operations in bulk, we can write powershell script and to make things generic and configurable, we can use source of script be xml file.In the sample code below, I will use xml as source of input to perform these operations. Structure of these xmls can be modified based on need however while making changes in xml we also need to make change in powershell to consider this structure change.
For Merge -
<Root>
<Merge>
<Term srcName ="T2" destName="T1"></Term>
</Merge>
</Root>
For merging we can define the xml in format mentioned above (I am assuming there is only one term wih any name, if not then we need to take guid of term)
sample code to merge term -
$taxonomySession = Get-SPTaxonomySession -Site "SiteURL"
$termStore = $taxonomySession.TermStores["Your Managed Metadata Service Name"]
$group = $termStore.Groups["Your Group Name"]
if($group -eq $null)
{
return
}
$termSet = $group.TermSets | Where-Object { $_.Name -eq $termSetName }
if($termSet -eq $null)
{
return
}
$movexml = [xml](Get-Content Merge.xml)
if($movexml.Root.ChildNodes.Count -gt 0) {
for($i = 0; $i -lt $movexml.Root.ChildNodes.Count; $i++) {
$OldTermName = $movexml.Root.ChildNodes.Item($i).Term.GetAttribute("srcName")
$newTermName = $movexml.Root.ChildNodes.Item($i).Term.GetAttribute("destName")
$Oldterm = $termSet.GetAllTerms() | Where-Object { $_.Name -eq $OldTermName }
$newterm = $termSet.GetAllTerms() | Where-Object { $_.Name -eq $newTermName }
if($Oldterm -eq $null)
{
Write-Output "Source Term is null"
}
elseif($newterm -eq $null)
{
Write-Output "Destination Term is null"
}
else
{
$Oldterm.Merge($newTerm)
}
}
}
$termStore.CommitAll();
For rename term-
<Root>
<Rename>
<Term oldName ="T1" newName="Term1"></Term>
</Rename>
</Root>
Powershell -
$movexml = [xml](Get-Content Rename.xml)
if($movexml.Root.ChildNodes.Count -gt 0) {
for($i = 0; $i -lt $movexml.Root.ChildNodes.Count; $i++) {
$OldTermName = $movexml.Root.ChildNodes.Item($i).Term.GetAttribute("oldName")
$newTermName = $movexml.Root.ChildNodes.Item($i).Term.GetAttribute("newName")
$term = $termSet.GetAllTerms() | Where-Object { $_.Name -eq $OldTermName }
if($term -eq $null)
{
Write-Output "Source Term is null"
}
else
{
$term.Name = $newTermName
}
}
}
Move Xml -
<Root>
<Move>
<Source>
<Term name ="T4">
</Term>
</Source>
<Destination>
<Term name="T1">
</Term>
</Destination>
</Move>
</Root>
Move powershell -
function MoveTerm
{
param($sourceTerm, $destTerm, $DestTermNode)
if($DestTermNode.ChildNodes.Count -gt 0) {
$childdestTermName = $DestTermNode.Term.GetAttribute("name")
$childdestTermNode = $DestTermNode.Term
$childestTerm = $destTerm.Terms | Where-Object { $_.Name -eq $childdestTermName }
MoveTerm $sourceTerm $childestTerm $childdestTermNode
}
else
{
$sourceTerm.Move($destTerm)
}
}
$movexml = [xml](Get-Content Move.xml)
if($movexml.Root.ChildNodes.Count -gt 0) {
Write-OutPut "Move process Begin"
for($i = 0; $i -lt $movexml.Root.ChildNodes.Count; $i++) {
$sourceTermName = $movexml.Root.ChildNodes.Item($i).Source.Term.GetAttribute("name")
$destTermName = $movexml.Root.ChildNodes.Item($i).Destination.Term.GetAttribute("name")
$DestTermNode = $movexml.Root.ChildNodes.Item($i).Destination.Term
$sourceTerm = $termSet.Terms | Where-Object { $_.Name -eq $sourceTermName }
$destTerm = $termSet.Terms | Where-Object { $_.Name -eq $destTermName }
if($sourceTerm -eq $null)
{
Write-Output "Source Term is null"
}
elseif($destTerm -eq $null)
{
Write-Output "Destination Term is null"
}
else
{
MoveTerm $sourceTerm $destTerm $DestTermNode
}
}
Write-OutPut "Move process End"
}
Comments
Anonymous
April 26, 2012
while renaming the term getting error...property name is not exist and not settableAnonymous
April 28, 2012
Could you please check if you have permission to update the term name. Term Name property is settable. msdn.microsoft.com/.../microsoft.sharepoint.taxonomy.term_members.aspxAnonymous
April 28, 2012
One more thing I suspect is...please check if there are more than one term with that name in your term set. If Yes..please specifiy the Id of term, while finding term $term = $termSet.GetAllTerms() | Where-Object { $.Id -eq $TermGuidToSearch } Or if you want to rename all the terms with that name...iterate through all term in $termColl = $termSet.GetAllTerms() | Where-Object { $.Name -eq $OldTermName } and rename....reason - if there are more than one term with that name it will return term collection.Anonymous
November 19, 2012
Hi Kaushal, How do i rename a group and term store the field is faded away ? Please let me know ?Anonymous
August 06, 2013
You can use TermStore.Name and SPGroup.Name property respectively to update the name. Please refer - msdn.microsoft.com/.../microsoft.sharepoint.spgroup.name.aspx msdn.microsoft.com/.../microsoft.sharepoint.taxonomy.termstore.name(v=office.15).aspx