Set List Item by Metadata
This PnP PowerShell script reads a CSV file and updates SharePoint Online list items by matching a metadata value — such as a site name stored in the Title field — rather than requiring the numeric item ID. It looks up each matching item with a CAML query, then updates one or more fields per row.
Purpose
This script helps with SharePoint list management by:
- Reading a site name (or other metadata value) and update values from a CSV file
- Querying the list for the item whose
Titlefield matches that value - Updating multiple field values on the matched item in a single operation
- Writing a timestamped report file for tracking updates
Prerequisites
- PnP PowerShell module installed
- Site collection administrator or list edit permissions
- A CSV file (e.g.
ComplexUpdate.csv) with aSitecolumn matching the value stored in the list'sTitlefield - The internal field names of the columns you wish to update
CSV Format
The CSV file should include a Site column matching the Title field of the target list item, plus one column per field being updated. Example:
Site,Column1,Column2,Column3
https://tenantName.sharepoint.com/sites/siteName,Valuse1,Value11,Value111
PowerShell Script
$SiteUrl = 'https://SiteName.sharepoint.com/sites/SiteName'
$ClientId = ""
$ListName = "<listName>"
if ($null -eq $SiteUrl) { exit; }
Connect-PnPOnline -Url $SiteURL -Interactive -ClientId $ClientId
Write-Host [Success] Connected to $SiteUrl -ForegroundColor Green
$csvfile = "ComplexUpdate.csv"
$sites = Import-Csv $csvfile
$mydatestring=get-date -format yyyyMMddHHmm
$Statusreport= "Report-ComplexUpdates-$mydatestring.csv"
"Site,Column1,Column2,Column3" | add-content $Statusreport
#=========================================================
#1. Get URLS from CSV Report & update Current Value
#=========================================================
Foreach ($site in $sites)
{
#================= query list item by Title======================
$getCurrentStatus=$null
$CurrentStatus="<View><Query><Where><Eq><FieldRef Name='Title'/><Value Type='Text'>$($site.'Site')</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>"
$getCurrentStatus=Get-PnPListItem -List $ListName -Query $CurrentStatus -ErrorAction SilentlyContinue
#==================Update fields===================
Set-PnPListItem -List $ListName -Identity $getCurrentStatus -Values @{"Column1" = "$($site.'Column1')";"Column2" = "$($site.'Column2')";"Column3" = "$($site.'Column3')"}
#================= update list item END======================
}
write-host "Completed"
Usage Notes
- Replace
$SiteUrland$ClientIdwith your environment values —$ClientIdrequires a registered Entra ID app registration - Replace
$ListNamewith the internal name of your target list - The script matches on the list's
Titlefield — confirm that's where your lookup value (e.g. site URL) is stored before running - Replace
Column1,Column2,Column3with the internal names of the fields you want to update, and make sure the CSV headers match exactly - If no item matches a given row,
Get-PnPListItemreturns nothing and the subsequentSet-PnPListItemcall will fail for that row — wrap it in error handling if you need the loop to continue past a miss - Test against a non-production list before running on live data