Data / Configure / Report

File Version Trimmer

This sample shows how to delete a number of file versions to reduce SharePoint Storage

Summary

SharePoint storage is expensive and often we don't need 500 versions of a huge PowerPoint file. One option could be to change the default number of file versions from 500 to e.g. 50. However, if you already have a file with 250 versions this change WILL NOT remove existing versions. This sample shows how you can trim back the number of file versions in a specific Document Library in a Site Collection. Be aware that the change will take up to 24 hours to be visible in the SharePoint Admin center.

Example Screenshot

powershell
$ClientId = "XXXXXX"
$TenantName = "contoso.onmicrosoft.com"
$thumbprint = "ZZZZZZZ"
$SharePointAdminSiteURL = "https://contoso-admin.sharepoint.com"

$conn = Connect-PnPOnline -Url $SharePointAdminSiteURL -ClientId $ClientId -Tenant $TenantName -CertificatePath "C:\Users\you\certificate.pfx" -CertificatePassword (ConvertTo-SecureString -AsPlainText -Force "CentificatePassword") -ReturnConnection

#Set Variables
$outputPath = "C:\temp\versiontrimmer\" 
$arraylist = New-Object System.Collections.ArrayList

function DeleteVersions($siteUrl, $ListName, $listitemID, $versionsToKeep)
{
    try 
    {
        $siteconn = Connect-PnPOnline -Url $siteUrl -ClientId $ClientId -Tenant $TenantName -CertificatePath "C:\Users\KasperLarsen\IAGovApp.pfx" -CertificatePassword (ConvertTo-SecureString -AsPlainText -Force "IAGovApp") -ReturnConnection

        #get list of all lists in this site
        if($ListName)
        {
            $list = Get-PnPList -Identity $ListName -Connection $siteconn -ErrorAction SilentlyContinue
            if($list)
            {
                $listitems = Get-PnPListItem -List $list -Connection $siteconn
                if($listitemID)
                {
                    $listitem = $listitems | Where-Object {$_.ID -eq $listitemID}
                    if($listitem)
                    {
                        $file = Get-PnPFile  -Url $listitem["FileRef"] -AsFileObject -ErrorAction SilentlyContinue -Connection $siteconn           
                        if($file)
                        {
                            $fileversions = Get-PnPFileVersion -Url $listitem["FileRef"] -Connection $siteconn
                            if($fileversions)
                            {
                                if($fileversions.Count -gt $versionsToKeep)
                                {
                                    $DeleteVersionList = ($fileversions[0..$($fileversions.Count - $versionsToKeep)])
                                    $element = "" | Select-Object SiteUrl, siteName, ListTitle, itemName, fileType, Modified, versioncount, FileSize
                                    $element.SiteUrl = $siteUrl
                                    $element.siteName = $siteconn.Name
                                    $element.ListTitle = $list.Title
                                    $element.itemName = $file.Name
                                    $fileextention = $item["FileLeafRef"].Substring($item["FileLeafRef"].LastIndexOf(".")+1)
                                    $element.fileType = $fileextention
                                    $element.Modified = $file.TimeLastModified.tostring()
                                    $element.versioncount = $fileversions.Count
                                    $element.fileSize = $file.Length
                                    
                                    $arraylist.Add($element) | Out-Null                        
                                    
                                    foreach($VersionToDelete in $DeleteVersionList) 
                                    {
                                        Remove-PnPFileVersion -Url $listitem["FileRef"] -Identity $VersionToDelete.Id –Force -Connection $siteconn            
                                    }
                                }
                                else {
                                    write-host "no versions to delete"
                                }
                            }                            
                        }
                        else {
                            write-host "file not found" -ForegroundColor Red
                        }
                    }
                }
                else 
                {
                    foreach($listitem in $listitems)
                    {
                        $file = Get-PnPFile  -Url $listitem["FileRef"] -AsFileObject -ErrorAction SilentlyContinue -Connection $siteconn           
                        if($file)
                        {
                            $fileversions = Get-PnPFileVersion -Url $listitem["FileRef"] -Connection $siteconn
                            if($fileversions)
                            {
                                Write-Host "fileversions found $($fileversions.Count)"
                                if($fileversions.Count -gt $versionsToKeep)
                                {
                                    $number =$fileversions.Count - $versionsToKeep
                                    $DeleteVersionList = ($fileversions[0..$number])
                                    $element = "" | Select-Object SiteUrl, ListTitle, itemName, fileType, Modified, versioncount, FileSize
                                    $element.SiteUrl = $siteUrl
                                    $element.ListTitle = $list.Title
                                    $element.itemName = $file.Name
                                    $fileextention = $listitem["FileLeafRef"].Substring($listitem["FileLeafRef"].LastIndexOf(".")+1)
                                    $element.fileType = $fileextention
                                    $element.Modified = $file.TimeLastModified.tostring()
                                    $element.versioncount = $fileversions.Count
                                    $element.fileSize = $file.Length
                                    
                                    $arraylist.Add($element) | Out-Null
                                    foreach($VersionToDelete in $DeleteVersionList) 
                                    {
                                        Remove-PnPFileVersion -Url $listitem["FileRef"] -Identity $VersionToDelete.Id –Force -Connection $siteconn            
                                    }
                                }
                                else {
                                    write-host "no versions to delete"
                                }                                
                            }
                            else {
                                write-host "fileversions not found" -ForegroundColor Yellow
                            }                            
                        }
                        else {
                            write-host "file not found" -ForegroundColor Yellow
                        }
                    }
                }
            }            
        }
        else {
            # you can trim all lists in a site here
        }            
    }
    catch 
    {
        Write-Output "Ups an exception was thrown : $($_.Exception.Message)" -ForegroundColor Red
    }  
}

function Get-SiteCollections
{
    # this function is just a way to get the site collections that are in scope for the trimming
    $SiteCollections = Get-PnPTenantSite -Connection $conn  
    Disconnect-PnPOnline -Connection $conn
    return $SiteCollections
}

# $allsitecollections = Get-SiteCollections
# foreach($SiteCollection in $SiteCollections)
# {
#     DeleteVersions -siteUrl $SiteCollection.Url -ListName "Shared Documents" -listitemID 1 -versionsToKeep 20   
# }


#get total storage use for this site collection
$siteUrl = "https://contoso.sharepoint.com/sites/aSpecificSiteCollection"
$site = Get-PnPTenantSite -Connection $conn -Url $siteUrl -Detailed
$siteStorage = $site.StorageUsageCurrent
$siteStorage = $siteStorage / 1024 
$siteStorage = [Math]::Round($siteStorage,2)
write-host "site storage $siteStorage GB"

DeleteVersions -siteUrl $siteUrl -ListName "DocLibMajors"  -versionsToKeep 10
$arraylist | Export-Csv -Path "C:\temp\versiontrimmer.csv" -NoTypeInformation -Force -Encoding utf8BOM -Delimiter "|"

Source Credit

The 'PnP PowerShell Enhanced Version Control Batch Delete Job' sample first appeared on Enhanced Version Controls/Intelligent Versioning Trim with PowerShell

Contributors

Author(s)
Kasper Larsen
Nanddeep Nachan
Reshmee Auckloo (script)

Disclaimer

THESE SAMPLES ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

Tool documentation & references

Keep exploring