Import SharePoint Term Synonyms with PowerShell
This post provides a PowerShell script to import synonyms (labels) into a SharePoint term set using the PnP.PowerShell module. The sample using PnP PowerShell to import a csv file (same format you would use for import via UI for a term set but with an additional column for Synonyms delimited by |)
Prerequisites
- Install the PnP.PowerShell module (run as an admin):
Install-Module PnP.PowerShell -Scope CurrentUser
- An Azure AD app or other authentication method with sufficient permissions to manage taxonomy/term store, or use interactive
Connect-PnPOnline.
Usage
- Update the variables at the top of the script (
$envTermGroup,$termSId,$csvPath, and connection settings). - Run the script in PowerShell where you have PnP modules available.
$envTermGroup = "Document Management Tags"
$termSId = "b6ddada5-25b5-xxx-xxxx-b473235d6278" # replace with your TermSet ID
$csvPath = "C:\Users\you\path\Import.csv"
$logFile = ".\term_synonyms_Log-$(Get-Date -Format "yyyyMMdd-HHmm").csv"
function Log-Message {
param (
[string]$Message,
[string]$Status
)
switch ($Status) {
"Success" { $color = "Green" }
"Info" { $color = "Blue" }
"Error" { $color = "Red" }
default { $color = "White" }
}
Write-Host -ForegroundColor $color "$Status => $Message"
$logEntry = [PSCustomObject]@{
Timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
Message = $Message
Status = $Status
}
$logEntry | Export-Csv -Path $logFile -Append -NoTypeInformation
}
# Example: connect using an app-only client id (replace with your method)
$clientId = "xxxx"
Connect-PnPOnline -Url https://contoso.sharepoint.com/ -ClientId $clientId
Log-Message -Message "Connected to SharePoint" -Status "Info"
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
Function Add-Synonyms($ImportCsv, $termsetId, $termGroup)
{
Import-Csv $ImportCsv | ForEach-Object {
$labels = $($_.Synonyms)
if ($labels) {
$i = 7
$termName = ""
while (($termName -eq "" -or $termName -eq $null) -and $i -ge 1) {
$termName = $($_.$("Level " + $i.ToString() + " Term"))
$i--
}
if ($termName) {
try {
if ($i -eq 0) {
$term = Get-PnPTerm -Identity $termName -TermSet $termsetId -TermGroup $termGroup
}
else {
$term = Get-PnPTerm -Identity $termName -TermSet $termsetId -TermGroup $termGroup -Recursive
}
Log-Message -Message "Processing $termName" -Status "Info"
}
catch {
Log-Message -Message "$termName not found" -Status "Error"
}
if (!$term) {
Log-Message -Message "$termName not found" -Status "Error"
}
if ($term) {
foreach ($l in $labels.split(',')) {
$l = $l.trim()
if ($l) {
try {
$otherLabels = Get-PnPTermLabel -Lcid 1033 -Term $term
$otherLabel = ""
foreach ($label in $otherLabels) {
if ($label.Value -eq $l) {
$otherLabel = $label.Value.trim()
}
}
if (!$otherLabel) {
$term.CreateLabel($l, 1033, $false)
Start-Sleep -Seconds 5
Log-Message -Message "Adding label $l to term $termName" -Status "Success"
}
}
catch {
Log-Message -Message "$($_.Exception) adding $l" -Status "Error"
}
}
}
}
}
}
}
}
# Create Term Group if missing
try {
$termGroup = Get-PnPTermGroup -Identity $envTermGroup -ErrorAction SilentlyContinue
if (!$termGroup) {
New-PnPTermGroup -GroupName $envTermGroup
Log-Message -Message "Created Term Group $envTermGroup" -Status "Success"
}
}
catch {
Log-Message -Message "Term Group already exists or cannot be created" -Status "Info"
}
# Import Term Set and add synonyms
Import-PnPTermSet -GroupName $envTermGroup -TermSetId $termSId -Path $csvPath -SynchronizeDeletions
Start-Sleep -Seconds 5
Add-Synonyms $csvPath $termSId $envTermGroup