Introduction
Managed Metadata is a powerful feature in SharePoint that allows you to create and use hierarchical sets of terms to classify and organize your content. You can use Managed Metadata columns to associate your items with terms from a specific term set, or allow users to enter their own terms.
However, sometimes you may need to copy or move the values of a Managed Metadata column to another column in the same list. For example, you may have created a new term set and want to update the existing items with the new terms, or you may want to rename or restructure your Managed Metadata column and preserve the old values. In this blog post, I will show you how to use a PowerShell script to achieve this task in SharePoint Online.
Prerequisites
- You need to have PnP PowerShell module installed on your machine. You can install it using the command Install-Module SharePointPnPPowerShellOnline.
- You need to have a SharePoint Online site with a list that contains two Managed Metadata columns. The source column is the one that has the values you want to copy, and the target column is the one that will receive the values. The target column should have a term set that includes the terms from the source column.
- You need to have the site URL, the list name, and the internal names of the source and target columns. You can find the internal names by going to the list settings and clicking on the column names.
Setting Up the Script
First, you’ll need to connect to your SharePoint site. For this example, replace YOURTENANT
with your actual tenant name and SITEA
with the site you want to connect to:
# Connect to the SharePoint site
$siteUrl = "https://YOURTENANT.sharepoint.com/sites/SITEA"
Connect-PnPOnline -Url $siteUrl -Interactive
This command initiates a connection to your specified SharePoint site, prompting you to log in interactively.
Identifying the List and Columns
Next, define the list you are working with and the specific fields (columns) you will be copying data from and to. Replace LISTNAME
with your list name, OLDFIELD
with the source field name, and NEWFIELD
with the target field name:
# Get the list
$listName = "LISTNAME"
$list = Get-PnPList -Identity $listName
# Specify the source and target Managed Metadata columns
$sourceColumnName = "OLDFIELD"
$targetColumnName = "NEWFIELD"
Retrieving List Items
You then need to retrieve all items from the list:
# Get all list items
$listItems = Get-PnPListItem -List $list
Processing Each List Item
The script iterates through each list item to read the source field value and copy it to the target field:
# Iterate through each list item
foreach ($item in $listItems) {
# Get the value of the source Managed Metadata column
$sourceValue = $item[$sourceColumnName]
# If the source value is not null, set the value of the target Managed Metadata column
if ($sourceValue -ne $null) {
$originalpath = $sourceValue.Label
$indexOf = $originalpath.IndexOf(":")
$LookUpValueNr = $originalpath.Substring(0, $indexOf)
$LookupValueName = $originalpath.Substring($indexOf + 1)
$NewValue = "TERMGROUP|TERMSET|"+$LookUpValueNr+"|"+$LookupValueName
Write-Host $NewValue
#Set Managed Metadata Column value in: "Group|Termset|Parent|Child" format
#Set-PnpTaxonomyFieldValue -ListItem $item.Id -InternalFieldName $targetColumnName -TermPath $NewValue
Set-PnPListItem -List $list -Identity $item.Id -Values @{$targetColumnName = $NewValue}
}
}
Code Breakdown: Iterating and Processing List Items
Iterating Through Each List Item
The foreach
loop is used to go through each item in the list:
foreach ($item in $listItems) {
- $listItems: This variable holds all the list items retrieved earlier using the
Get-PnPListItem
command. - $item: This represents the current item in the list being processed during each iteration of the loop.
Getting the Source Managed Metadata Column Value
Within the loop, the script retrieves the value of the source managed metadata column for the current item:
# Get the value of the source Managed Metadata column
$sourceValue = $item[$sourceColumnName]
- $sourceColumnName: This is the name of the column from which the value is being copied.
- $sourceValue: This variable will store the value of the managed metadata column for the current item.
Checking if the Source Value is Not Null
The script then checks if the sourceValue
is not null:
# If the source value is not null, set the value of the target Managed Metadata column
if ($sourceValue -ne $null) {
- This condition ensures that only items with a non-null value in the source column are processed further.
Extracting and Formatting the Term Path
If the source value is not null, the script proceeds to extract and format the term path:
$originalpath = $sourceValue.Label
$indexOf = $originalpath.IndexOf(":")
$LookUpValueNr = $originalpath.Substring(0, $indexOf)
$LookupValueName = $originalpath.Substring($indexOf + 1)
- $originalpath: This variable stores the label of the source value, which typically includes the term path.
- $indexOf: Finds the position of the colon (
:
) in theoriginalpath
, which is used to split the path into different parts. - $LookUpValueNr: Extracts the part of the path before the colon. This is usually a numeric value or identifier.
- $LookupValueName: Extracts the part of the path after the colon. This is usually the name of the term.
Constructing the New Value for the Target Column
The script then constructs the new value in the required format for the target managed metadata column:
$NewValue = "TERMGROUP|TERMSET|"+$LookUpValueNr+"|"+$LookupValueName
- $NewValue: Combines the term group, term set, and extracted parts (
$LookUpValueNr
and$LookupValueName
) to create the new value.
Displaying the New Value
For debugging or verification purposes, the script prints the new value:
Write-Host $NewValue
Setting the New Value in the Target Column
Finally, the script sets the new value in the target managed metadata column:
#Set Managed Metadata Column value in: "Group|Termset|Parent|Child" format
#Set-PnpTaxonomyFieldValue -ListItem $item.Id -InternalFieldName $targetColumnName -TermPath $NewValue
Set-PnPListItem -List $list -Identity $item.Id -Values @{$targetColumnName = $NewValue}
- Set-PnPListItem: This command updates the current item in the list with the new value for the target column.
- $targetColumnName: The name of the target column where the new value will be set.
- $item.Id: The unique identifier of the current list item being processed.
Disconnecting from SharePoint
Finally, disconnect from the SharePoint site:
# Disconnect from the SharePoint site
Disconnect-PnPOnline
Conclusion
This script ensures a smooth transfer of metadata values between fields, maintaining consistency across your SharePoint lists.
Full Script
# Connect to the SharePoint site
$siteUrl = "https://YOURTENANT.sharepoint.com/sites/SITEA"
Connect-PnPOnline -Url $siteUrl -Interactive
# Get the list
$listName = "LISTNAME"
$list = Get-PnPList -Identity $listName
# Specify the source and target Managed Metadata columns
$sourceColumnName = "OLDFIELD"
$targetColumnName = "NEWFIELD"
# Get all list items
$listItems = Get-PnPListItem -List $list
# Iterate through each list item
foreach ($item in $listItems) {
# Get the value of the source Managed Metadata column
$sourceValue = $item[$sourceColumnName]
# If the source value is not null, set the value of the target Managed Metadata column
if ($sourceValue -ne $null) {
$originalpath = $sourceValue.Label
$indexOf = $originalpath.IndexOf(":")
$LookUpValueNr = $originalpath.Substring(0, $indexOf)
$LookupValueName = $originalpath.Substring($indexOf + 1)
$NewValue = "TERMGROUP|TERMSET|"+$LookUpValueNr+"|"+$LookupValueName
Write-Host $NewValue
#Set Managed Metadata Column value in: "Group|Termset|Parent|Child" format
#Set-PnpTaxonomyFieldValue -ListItem $item.Id -InternalFieldName $targetColumnName -TermPath $NewValue
Set-PnPListItem -List $list -Identity $item.Id -Values @{$targetColumnName = $NewValue}
}
}
# Disconnect from the SharePoint site
Disconnect-PnPOnline