We apply Company logos across all SharePoint Online Site Collections and subsites. When a new logo is designed, I receive requests to update them. The PowerShell script below simplifies this process.
While running this script, you will get a window prompt to login with your Global Admin/SharePoint Admin account. Enter credentials and proceed forward.
# --------------------------
# Configuration
# --------------------------
$clientId = "12a34567-f123-4567-890e-1cch23456789"
$SiteCollectionUrl = "https://yourtenant.sharepoint.com/sites/company"
$LogoUrl = "https://yourtenant.sharepoint.com/sites/BrandGuide/Images/Company_Logo.png"
# Connect to root once (to enumerate subsites)
Connect-PnPOnline -Url $SiteCollectionUrl -Interactive -ClientId $clientId
# Get root + all subsites (recursive)
$webs = Get-PnPSubWeb -Recurse -IncludeRootWeb
# ---- Count of all sites (webs) ----
$totalSites = $webs.Count
Write-Host "Total sites (root + all subsites) found: $totalSites" -ForegroundColor Cyan
# Detect if your Connect-PnPOnline supports -ReturnConnection
$hasReturnConnection = (Get-Command Connect-PnPOnline).Parameters.ContainsKey("ReturnConnection")
$success = 0
$failed = 0
foreach ($w in $webs) {
try {
Write-Host "[$success/$totalSites] Updating logo for: $($w.Title) -> $($w.Url)" -ForegroundColor White
if ($hasReturnConnection) {
$conn = Connect-PnPOnline -Url $w.Url -Interactive -ClientId $clientId -ReturnConnection
Set-PnPWeb -Connection $conn -SiteLogoUrl $LogoUrl # Set-PnPWeb works on current web / via -Connection
}
else {
Connect-PnPOnline -Url $w.Url -Interactive -ClientId $clientId
Set-PnPWeb -SiteLogoUrl $LogoUrl #
}
$success++
Write-Host "SUCCESS: $($w.Url)" -ForegroundColor Green
}
catch {
$failed++
Write-Host "FAILED: $($w.Url) | $($_.Exception.Message)" -ForegroundColor Red
}
}
Write-Host "Logo update process complete." -ForegroundColor Cyan
Write-Host "Summary: Total=$totalSites | Success=$success | Failed=$failed" -ForegroundColor Yellow
The result shows as below.
