Auditing Unused SharePoint Sites using PnP PowerShell

Loading

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.

Leave a Reply

Your email address will not be published. Required fields are marked *