In SharePoint Online, over time, many sites become unused or inactive, leading to clutter, security risks, and storage inefficiencies. Regular auditing helps identify and manage unused sites, ensuring an optimized SharePoint environment.
Using PnP PowerShell, administrators can:
✔ Identify inactive SharePoint sites
✔ Analyze last activity date (file edits, page views, user logins, etc.)
✔ Generate reports of unused sites
✔ Notify site owners before taking action
✔ Automate the cleanup process
This guide provides a step-by-step approach to auditing unused SharePoint sites using PnP PowerShell.
Step 1: Install & Update PnP PowerShell
Ensure PnP PowerShell is installed or updated:
Install-Module -Name PnP.PowerShell -Force -AllowClobber
If already installed, update it:
Update-Module -Name PnP.PowerShell
Step 2: Connect to SharePoint Online
Connect to SharePoint Online Admin Center using PnP PowerShell:
Connect-PnPOnline -Url "https://yourtenant-admin.sharepoint.com" -Interactive
For app-based authentication, use:
$tenantId = "your-tenant-id"
$clientId = "your-client-id"
$clientSecret = "your-client-secret"
Connect-PnPOnline -Tenant $tenantId -ClientId $clientId -ClientSecret $clientSecret -Url "https://yourtenant-admin.sharepoint.com"
Step 3: Retrieve All SharePoint Sites
To get a list of all SharePoint sites, run:
$sites = Get-PnPTenantSite -IncludeOneDriveSites $false
$sites | Select-Object Url, Title, StorageUsage, LastContentModifiedDate | Format-Table -AutoSize
✔ Displays site URL, title, storage usage, and last modified date.
✔ Useful for identifying old or unused sites.
Step 4: Identify Unused SharePoint Sites
To filter sites inactive for over 6 months:
$thresholdDate = (Get-Date).AddMonths(-6)
$unusedSites = $sites | Where-Object { $_.LastContentModifiedDate -lt $thresholdDate }
$unusedSites | Select-Object Url, Title, LastContentModifiedDate | Format-Table -AutoSize
✔ Lists inactive sites based on their last content update.
✔ You can adjust the time frame by modifying -6
months.
Step 5: Export Inactive Site Report
To generate a CSV report for review:
$reportPath = "C:\Reports\UnusedSharePointSites.csv"
$unusedSites | Export-Csv -Path $reportPath -NoTypeInformation
Write-Host "Unused SharePoint Sites report saved at: $reportPath"
✔ This report helps track inactive sites before taking action.
Step 6: Check Site Usage via Audit Logs
To get audit logs for site usage (last access, file changes, logins):
$siteUrl = "https://yourtenant.sharepoint.com/sites/TestSite"
$logs = Search-UnifiedAuditLog -StartDate (Get-Date).AddMonths(-6) -EndDate (Get-Date) -RecordType SharePointFileOperation -Operations View, Edit, Delete -ObjectId $siteUrl
if ($logs) {
Write-Host "Activity found for $siteUrl"
} else {
Write-Host "No recent activity found for $siteUrl"
}
✔ Helps confirm if a site is truly inactive or has hidden activity.
Step 7: Notify Site Owners of Inactive Sites
To notify site owners about inactivity:
foreach ($site in $unusedSites) {
$owner = Get-PnPSiteOwner -Url $site.Url
$emailBody = "Hello, your SharePoint site '$($site.Title)' ($($site.Url)) has been inactive for over 6 months. Please confirm if it should be retained."
Send-MailMessage -To $owner -From "admin@yourcompany.com" -Subject "Inactive SharePoint Site Alert" -Body $emailBody -SmtpServer "smtp.yourcompany.com"
}
✔ Sends automated email alerts to site owners for action.
Step 8: Archive or Delete Unused Sites
To archive unused sites before deletion:
foreach ($site in $unusedSites) {
Write-Host "Archiving site: $($site.Url)"
Backup-PnPFile -Folder "/Shared Documents" -Path "C:\Backups\$($site.Title).zip" -Force
}
✔ Backs up site documents before deletion.
To delete unused sites after confirmation:
foreach ($site in $unusedSites) {
Write-Host "Deleting site: $($site.Url)"
Remove-PnPTenantSite -Url $site.Url -SkipRecycleBin -Force
}
✔ Removes inactive sites permanently.
Step 9: Automate Unused Site Auditing
To schedule automatic site audits, save the script as “AuditUnusedSites.ps1” and run it periodically:
$thresholdDate = (Get-Date).AddMonths(-6)
$sites = Get-PnPTenantSite -IncludeOneDriveSites $false
$unusedSites = $sites | Where-Object { $_.LastContentModifiedDate -lt $thresholdDate }
if ($unusedSites) {
$reportPath = "C:\Reports\UnusedSharePointSites.csv"
$unusedSites | Export-Csv -Path $reportPath -NoTypeInformation
Write-Host "Unused SharePoint Sites report saved at: $reportPath"
}
✔ Run via Task Scheduler or Azure Automation for periodic auditing.