Collaborate, Innovate, Automate

Create Term Store

This PnP PowerShell script automates the creation and management of term stores in SharePoint Online. Term stores provide centralized taxonomy management, enabling consistent tagging and metadata across your SharePoint environment.

Purpose

Term stores enable you to:

Prerequisites

PowerShell Script

# SharePoint Taxonomy Management Script
$AdminCenterURL = "https://tenantName-admin.sharepoint.com"
$TermGroupName = "Intranet_Taxonomy" # your group name here
$TermGroupDescription = "Terms used for the Intranet Taxonomy"
$ClientId = "" # your Client ID

# Set up logging
$ScriptPath = $PSScriptRoot
if (!$ScriptPath) { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
$LogFile = Join-Path $ScriptPath "TermStorecreation_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"

# Initialize CSV with headers
"Timestamp,Action,ItemType,ItemName,Status,Message" | Out-File -FilePath $LogFile -Encoding UTF8

# Function to write to both console and log file
function Write-Log {
    param(
        [string]$Message,
        [string]$Color = "White",
        [string]$Action,
        [string]$ItemType,
        [string]$ItemName,
        [string]$Status
    )

    $TimeStamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

    # Write to console with color
    Write-Host $Message -ForegroundColor $Color

    # Prepare CSV line
    $csvLine = [PSCustomObject]@{
        Timestamp = $TimeStamp
        Action = $Action
        ItemType = $ItemType
        ItemName = $ItemName
        Status = $Status
        Message = $Message
    }

    # Export to CSV
    $csvLine | Export-Csv -Path $LogFile -Append -NoTypeInformation
}


try {
    # Connect to SharePoint
    Write-Host "Connecting to SharePoint..." -ForegroundColor Cyan
    Connect-PnPOnline -Url $AdminCenterURL -Interactive -ClientId $ClientId
    Write-Host "Connected successfully" -ForegroundColor Green

    # Create or get the term group
    Write-Host "Checking term group..." -ForegroundColor Cyan
    $termGroup = $null
    try {
        $termGroup = Get-PnPTermGroup -Identity $TermGroupName -ErrorAction Stop
        Write-Host "Found existing term group" -ForegroundColor Green
    }
    catch {
        Write-Host "Creating new term group..." -ForegroundColor Yellow
        $termGroup = New-PnPTermGroup -Name $TermGroupName -Description $TermGroupDescription
        Write-Host "Term group created" -ForegroundColor Green
        Start-Sleep -Seconds 5  # Give SharePoint time to process
    }

    # Read and parse JSON
    Write-Host "Reading JSON file..." -ForegroundColor Cyan
    $jsonPath = Read-Host "Enter the path to your JSON file"
    $jsonContent = Get-Content -Path $jsonPath -Raw
    $taxonomyData = $jsonContent | ConvertFrom-Json

    # Process each term set
    foreach ($termSetGroup in $taxonomyData.TermGroups) {
        $termSetName = $termSetGroup.TermSet
        Write-Host "Processing term set: $termSetName" -ForegroundColor Cyan

        # Create or get term set
        $termSet = $null
        try {
            $termSet = Get-PnPTermSet -Identity $termSetName -TermGroup $TermGroupName -ErrorAction Stop
            Write-Host "Found existing term set: $termSetName" -ForegroundColor Green
        }
        catch {
            Write-Host "Creating new term set: $termSetName" -ForegroundColor Yellow
            try {
                $termSet = New-PnPTermSet -Name $termSetName -TermGroup $TermGroupName -Lcid 1033 -ErrorAction Stop
                Write-Host "Term set created: $termSetName" -ForegroundColor Green
                Start-Sleep -Seconds 3
            }
            catch {
                Write-Host "Error creating term set $termSetName : $($_.Exception.Message)" -ForegroundColor Red
                continue
            }
        }

        # Process terms
        foreach ($termName in $termSetGroup.Terms) {
            Write-Host "Processing term: $termName" -ForegroundColor Cyan
            try {
                # Check if term exists
                $existingTerm = Get-PnPTerm -TermSet $termSetName -TermGroup $TermGroupName -Identity $termName -ErrorAction SilentlyContinue

                if ($existingTerm) {
                    Write-Host "Term already exists: $termName" -ForegroundColor Yellow
                }
                else {
                    # Create new term
                    $newTerm = New-PnPTerm -TermSet $termSetName -TermGroup $TermGroupName -Name $termName -ErrorAction Stop
                    Write-Host "Created term: $termName" -ForegroundColor Green
                    Start-Sleep -Milliseconds 500
                }
            }
            catch {
                Write-Host "Error creating term $termName : $($_.Exception.Message)" -ForegroundColor Red
            }
        }

        # Add delay between term sets
        Start-Sleep -Seconds 3
    }
}
catch {
    Write-Host "Critical error: $($_.Exception.Message)" -ForegroundColor Red
}
finally {
    # Disconnect PnP Session if connected
    if (Get-PnPConnection) {
        Write-Log -Message "Disconnecting from SharePoint..." -Color Cyan -Action "Disconnect" -ItemType "SharePoint" -ItemName $AdminCenterURL -Status "Started"
        Disconnect-PnPOnline
        Write-Log -Message "Disconnected from SharePoint successfully" -Color Green -Action "Disconnect" -ItemType "SharePoint" -ItemName $AdminCenterURL -Status "Success"
    }

    Write-Log -Message "Script execution completed. Log file saved to: $LogFile" -Color Yellow -Action "Script" -ItemType "Global" -ItemName "Complete" -Status "Success"
}

JSON Configuration File

{
  "TermGroups": [
    {
      "TermSet": "Departments",
      "Terms": [
        "Information Technology",
        "Human Resources",
        "Finance",
        "Sales",
        "Marketing",
        "Operations"
      ]
    },
    {
      "TermSet": "Document Types",
      "Terms": [
        "Policy",
        "Procedure",
        "Training Material",
        "Project Document",
        "Meeting Minutes",
        "Report"
      ]
    },
    {
      "TermSet": "Locations",
      "Terms": [
        "Valencia",
        "Madrid",
        "Barcelona",
        "Seville",
        "Bilbao"
      ]
    },
    {
      "TermSet": "Project Status",
      "Terms": [
        "Planning",
        "In Progress",
        "On Hold",
        "Completed",
        "Cancelled"
      ]
    }
  ]
}

Usage Notes