A small, opinionated set of scripts to trim file version history in SharePoint Online document libraries using PnP.PowerShell + CSOM.
It is designed to be:
- Safe-ish by default (first run per site is forced Dry Run)
- Low memory (streams list items, does not build a giant work list)
- Resilient (per-file deletion in chunks + retry/backoff)
- Quiet (logs only exceptions/skips, not every successful delete)
PNP-TrimVersions.ps1
DefinesInvoke-PnPVersionTrim(dot-source this).SPO-Trim-Orchestrator.ps1
Loops over many sites from a CSV. Does not manage auth; it prompts you to runConnect-PnPOnlineper site.New-TrimTemplates.ps1
Generates template CSV/YAML config files.PerfMode.ps1
Optional local "Boost/Restore" helper. Conservative by design.
Install-Module PnP.PowerShell -Scope CurrentUser# 1) Connect
Connect-PnPOnline -Url "https://tenant.sharepoint.com/sites/Finance" -Interactive
# 2) Load the tool
. .\PNP-TrimVersions.ps1
# 3) Dry run (first run is ALWAYS dry-run)
Invoke-PnPVersionTrim -LibraryTitle "Documents" -OlderThanDays 45
# 4) Real delete (2nd run+)
Invoke-PnPVersionTrim -LibraryTitle "Documents" -OlderThanDays 45 -DeleteInvoke-PnPVersionTrim -AllLibraries -OlderThanDays 60
Invoke-PnPVersionTrim -AllLibraries -OlderThanDays 60 -DeleteLibraries.csv
LibraryTitle
Documents
Shared DocumentsInvoke-PnPVersionTrim -LibraryCsvPath .\Trim-Config\Libraries.csv -OlderThanDays 45
Invoke-PnPVersionTrim -LibraryCsvPath .\Trim-Config\Libraries.csv -OlderThanDays 45 -DeleteBy default, only exceptions/skips are logged:
-ExceptionCsvPath(CSV)-TextLogPath(text)
Example:
Invoke-PnPVersionTrim -AllLibraries -OlderThanDays 60 -Delete `
-ExceptionCsvPath .\Logs\Exceptions.csv `
-TextLogPath .\Logs\Run.logInvoke-PnPVersionTrim -AllLibraries -OlderThanDays 60 -Delete -MeasureLibrarySizesSkipNameContains.csv
Token
Budget
Quarterly
Checklist
2024Invoke-PnPVersionTrim -AllLibraries -OlderThanDays 60 -Delete -SkipNameContainsCsvPath .\Trim-Config\SkipNameContains.csv- Create
Sites.csv(template viaNew-TrimTemplates.ps1) - Run orchestrator:
.\SPO-Trim-Orchestrator.ps1 `
-SitesCsvPath .\Trim-Config\Sites.csv `
-TrimScriptPath .\PNP-TrimVersions.ps1Multi-site delete requires:
.\SPO-Trim-Orchestrator.ps1 `
-SitesCsvPath .\Trim-Config\Sites.csv `
-TrimScriptPath .\PNP-TrimVersions.ps1 `
-Delete `
-PilotKey I_RAN_A_PILOT- Deletes are done via CSOM
File.VersionsandDeleteObject()calls, committed withExecuteQuery(). - If the tool stops mid-run, you can rerun it. It is not a "transaction" and does not corrupt libraries.
- SharePoint will block deletes under retention/holds/records. Those show up in the Exceptions CSV.