Create SharePoint SPO Navigation links with PowerShell and CSV for Top Navigation and Quick Launch

Step by step demo how to populate the Top Navigation bar with PowerShell PS1 and CSV automation. Attention given to parent > child relationship and how links are nested for compatibility to many branding scenarios. Also supports both QuickLaunch (left) and TopNavigation (top) placement. Cheers

VIDEO

CODE – PS1

function Main() {
    # Load PnP PowerShell Module
    #Install-Module "PnP.PowerShell" -MaxVersion 1.13 -Scope CurrentUser
    Import-Module "PnP.PowerShell"
 
    # Target SharePoint site URL
    $tenant = "https://test.sharepoint.com"
    $url = "https://spjeffdev.sharepoint.com/sites/Communication"
    $location = "QuickLaunch"
    # Connect to SharePoint Online site
    Connect-PnPOnline -Url $url -UseWebLogin
    # Get the current web to display Title and URL
    Get-PnPWeb
    # Read current top navigation
    $topNav = Get-PnPNavigationNode -Location $location
    Write-Host "Current Top Navigation Links:"
    foreach ($node in $topNav) {
        Write-Host "- $($node.Title): $($node.Url)"
    }
    # Read CSV with schema (ID,Parent,Title,URL) of desired top navigation links including primary key ID and ParentID for parent-child relationships
    $csvPath = ".\Fill-Top-Nav.csv"
    $topNavLinks = Import-Csv -Path $csvPath
    # Create top navigation links (if missing) from CSV
    foreach ($link in $topNavLinks) {
        $existingLink = Get-PnPNavigationNode -Location $location | Where-Object { $_.Title -eq $link.Title }
        if (-not $existingLink) {
            Write-Host "Adding top navigation link: $($link.Title)"
            # For parent-child relationships, find the parent node by ParentID
            if ($link.ParentID -ne 0) {
                $parentLink = $topNavLinks | Where-Object { $_.ID -eq $link.ParentID }
                $parentNode = Get-PnPNavigationNode -Location $location | Where-Object { $_.Title -eq $parentLink.Title }
                if ($parentNode) {
                    # SCENARIO 1 - Create with Parent
                    $url = $tenant + $link.URL +"/"
                    Write-Host $url -Fore Yellow
                    Add-PnPNavigationNode -Title $link.Title -Url $url -Location $location -Parent $parentNode.Id
                    Write-Host "Link created [$($link.Title)] under parent [$($parentLink.Title)]" -ForegroundColor "Green"
                }
                else {
                    Write-Host "Parent not found for [$($link.Title)]" -ForegroundColor "Yellow"
                }
            }
            else {
                # SCENARIO 2 - Create without Parent
                $url = $tenant + $link.URL +"/"
                Write-Host $url -Fore Yellow
                Add-PnPNavigationNode -Title $link.Title -Url $url -Location $location
            }
        }
        else {
            Write-Host "Link already exists [$($link.Title)]" -ForegroundColor "Green"
        }
    }
}
# Open Log
$prefix = $MyInvocation.MyCommand.Name
$host.UI.RawUI.WindowTitle = $prefix
$stamp = Get-Date -UFormat "%Y-%m-%d-%H-%M-%S"
Start-Transcript "$PSScriptRoot\log\$prefix-$stamp.log"
$start = Get-Date
# Run Main
Main
# Close Log
$end = Get-Date
$totaltime = $end - $start
Write-Host "`nTime Elapsed: $($totaltime.tostring("hh\:mm\:ss"))"
Stop-Transcript

CODE – CSV

ID,ParentID,Title,URL
1,0,Business Services,/sites/Communication/Business Services
2,1,Business Services Forms,/sites/Communication/Business Services/BusinessServices-Forms
3,0,Communications,/sites/Communication/Communications
4,3,Placeholder,/sites/Communication/Communications/Placeholder
5,0,Resources,/sites/Communication/Resources
6,5,Records,/sites/Communication/Records
7,0,Director Office,/sites/Communication/DirectorOffice
8,7,Placeholder,/sites/Communication/DirectorsOffice/PH
11,0,Finance,/sites/Communication/Finance
12,0,Operations and Planning,/sites/Communication/OperationsPlanning
13,0,Health,/sites/Communication/Health
13,0,Inventory,/sites/Communication/Inventory
14,0,Planning,/sites/Communication/Planning

REFERENCES

Leave a Comment

Return to Top ▲Return to Top ▲