Updating metadata one item at a time is painfully slow and hits throttling limits. Use PnP PowerShell's batching capabilities to process hundreds of items efficiently.
First, prepare your data in CSV format with these columns:
ServerRelativeUrl,ProjectID,Department,Status
/sites/yoursite/Shared Documents/Project1/doc1.docx,PRJ001,Engineering,Active
/sites/yoursite/Shared Documents/Project1/doc2.docx,PRJ001,Engineering,Complete
/sites/yoursite/Shared Documents/Project2/doc3.docx,PRJ002,Marketing,Active
Run this optimized batch update script:
# Bulk metadata update with batching and error handling
$csvPath = "C:\temp\metadata_updates.csv"
$libraryName = "Documents"
$batchSize = 100
# Initialize counters
$totalProcessed = 0
$errors = @()
# Create initial batch
$batch = New-PnPBatch
# Process CSV file
Import-Csv $csvPath | ForEach-Object {
try {
# Get the list item from file URL
$listItem = Get-PnPFile -Url $_.ServerRelativeUrl -AsListItem -ErrorAction Stop
# Prepare metadata values
$values = @{}
if ($_.ProjectID) { $values["ProjectID"] = $_.ProjectID }
if ($_.Department) { $values["Department"] = $_.Department }
if ($_.Status) { $values["DocumentStatus"] = $_.Status }
# Add to batch
Set-PnPListItem -List $libraryName -Identity $listItem.Id -Values $values -Batch $batch
# Execute batch when it reaches size limit
if ($batch.Operations.Count -ge $batchSize) {
Write-Host "Executing batch of $($batch.Operations.Count) operations..."
Invoke-PnPBatch $batch
$totalProcessed += $batch.Operations.Count
$batch = New-PnPBatch
Start-Sleep -Seconds 1 # Brief pause to avoid throttling
}
}
catch {
$errors += "Error processing $($_.ServerRelativeUrl): $($_.Exception.Message)"
}
}
# Execute remaining items in final batch
if ($batch.Operations.Count -gt 0) {
Write-Host "Executing final batch of $($batch.Operations.Count) operations..."
Invoke-PnPBatch $batch
$totalProcessed += $batch.Operations.Count
}
Write-Host "Total items processed: $totalProcessed"
if ($errors.Count -gt 0) {
Write-Host "Errors encountered:"
$errors | ForEach-Object { Write-Host $_ -ForegroundColor Red }
}
Verification: Check a few updated documents in SharePoint to confirm metadata was applied. Monitor the script output for any errors or throttling messages.
Pro tip: For libraries over 100,000 items, split your CSV into chunks of 5,000-10,000 rows and process them separately to avoid memory issues.