<# .SYNOPSIS Get-CMSharePointVersionReport.ps1 .DESCRIPTION Reports storage used per SharePoint site and the versioning settings of every document library (versioning on or off, major version limit, minor versions). Read-only: it changes nothing in your tenant. Why PnP.PowerShell: SharePoint Online Management Shell (Get-SPOSite) reports site storage, but it has no cmdlet that lists the document libraries in a site. PnP.PowerShell's Get-PnPList does, so this script uses PnP for both parts. Provided by cloud-migrations.au as is; test before use. Read the script before you run it and try it in a test tenant first. .NOTES Requirements - PowerShell 7.4 or later (required by PnP.PowerShell 3.x) - Install-Module PnP.PowerShell -Scope CurrentUser - An Entra ID app registration for PnP (Register-PnPEntraIDAppForInteractiveLogin) - SharePoint Administrator, plus read access to the sites you report on Commands used (documented by the PnP PowerShell project): Connect-PnPOnline -Url -Interactive -ClientId, Get-PnPTenantSite, Get-PnPList -Includes List properties (EnableVersioning, MajorVersionLimit, EnableMinorVersions, MajorWithMinorVersionsLimit, BaseTemplate, Hidden) are SharePoint List properties documented by Microsoft. BaseTemplate 101 is a document library. .EXAMPLE ./Get-CMSharePointVersionReport.ps1 -AdminUrl https://contoso-admin.sharepoint.com -ClientId 00000000-0000-0000-0000-000000000000 .EXAMPLE ./Get-CMSharePointVersionReport.ps1 -AdminUrl https://contoso-admin.sharepoint.com -ClientId 00000000-0000-0000-0000-000000000000 -SiteUrlFilter /sites/finance #> [CmdletBinding()] param( [Parameter(Mandatory = $true)][string]$AdminUrl, [Parameter(Mandatory = $true)][string]$ClientId, [string]$SiteUrlFilter = '', [switch]$IncludeHiddenLists, [string]$OutputPath = (Join-Path -Path (Get-Location) -ChildPath ('SharePointVersionReport_{0}.csv' -f (Get-Date -Format 'yyyyMMdd_HHmm'))) ) $ErrorActionPreference = 'Stop' # Copy the site columns into a new ordered row function Copy-CMRow { param($Source) $copy = [ordered]@{} foreach ($k in $Source.Keys) { $copy[$k] = $Source[$k] } return $copy } # 1. Connect to the admin URL and list sites (Get-PnPTenantSite leaves out OneDrive sites by default) try { Write-Host "Connecting to $AdminUrl ..." $adminConn = Connect-PnPOnline -Url $AdminUrl -Interactive -ClientId $ClientId -ReturnConnection Write-Host 'Reading the list of sites...' $sites = @(Get-PnPTenantSite -Connection $adminConn) } catch { Write-Error "Could not connect or list sites: $($_.Exception.Message)" return } if ($SiteUrlFilter) { $sites = @($sites | Where-Object { $_.Url -like "*$SiteUrlFilter*" }) } Write-Host ("Found {0} sites to check." -f $sites.Count) $results = New-Object System.Collections.Generic.List[object] $i = 0 foreach ($site in $sites) { $i++ Write-Progress -Activity 'Reading library version settings' -Status ("{0} of {1}: {2}" -f $i, $sites.Count, $site.Url) -PercentComplete (($i / [math]::Max($sites.Count, 1)) * 100) $base = [ordered]@{ SiteUrl = $site.Url SiteTitle = $site.Title SiteTemplate = $site.Template SiteStorageUsageCurrent = $site.StorageUsageCurrent SiteStorageQuota = $site.StorageQuota } try { $siteConn = Connect-PnPOnline -Url $site.Url -Interactive -ClientId $ClientId -ReturnConnection $lists = Get-PnPList -Connection $siteConn -Includes EnableVersioning, MajorVersionLimit, EnableMinorVersions, MajorWithMinorVersionsLimit, BaseTemplate, Hidden, ItemCount, RootFolder $libraries = @($lists | Where-Object { $_.BaseTemplate -eq 101 -and ($IncludeHiddenLists -or -not $_.Hidden) }) foreach ($lib in $libraries) { $row = Copy-CMRow $base $row.LibraryTitle = $lib.Title $row.LibraryUrl = $lib.RootFolder.ServerRelativeUrl $row.ItemCount = $lib.ItemCount $row.EnableVersioning = $lib.EnableVersioning $row.MajorVersionLimit = $lib.MajorVersionLimit $row.EnableMinorVersions = $lib.EnableMinorVersions $row.MajorWithMinorVersionsLimit = $lib.MajorWithMinorVersionsLimit $row.Error = '' $results.Add([pscustomobject]$row) } } catch { $row = Copy-CMRow $base $row.LibraryTitle = ''; $row.LibraryUrl = ''; $row.ItemCount = '' $row.EnableVersioning = ''; $row.MajorVersionLimit = ''; $row.EnableMinorVersions = '' $row.MajorWithMinorVersionsLimit = '' $row.Error = $_.Exception.Message $results.Add([pscustomobject]$row) } } Write-Progress -Activity 'Reading library version settings' -Completed # 2. Export try { $results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 $failed = @($results | Where-Object { $_.Error }).Count Write-Host ("Done. {0} rows written, {1} sites could not be read." -f $results.Count, $failed) Write-Host "Report saved to: $((Resolve-Path -Path $OutputPath).Path)" } catch { Write-Error "Could not write the CSV to $OutputPath : $($_.Exception.Message)" }