Limit Versioning and Delete Old Versions in SharePoint
In one of my SharePoint implementation, Defined the governance policy for versioning as: "Only 5 Major and 5 Minor versions should be kept.". So placed that in End-user self-service Portal site. But who cares? users setup up their document libraries/Lists to an unlimited number of versions, and asking for Increasing the Site quota quite often.
On analyzing the site space figured out: For a 1GB site, versions are occupying nearly 300MB!!! So, I wanted to clean-up the versions except for the last 5 minor/Last 5 Major. Oh, Yeah, to set versioning limit in SharePoint, Just get into the List/Library settings > Versioning settings then setup the versioning limits.
Quite simple, Isn't it? Ah, but the user has 100+ libraries where unlimited number of versions enabled! OMG!!!
Limit number of versions in SharePoint with PowerShell
PowerShell comes to rescue again! Here is the code to delete the older versions, except the last 5 major and minor.
In case, You want to disable version history for a particular list or library, use this PowerShell script:
Ok, What about cleaning the Old versions?
I have set-upped versioning limits, Will it delete the older version beyond my limit? unfortunately "NO"
Say for e.g. I have a Document in Document Library with an unlimited number of versions turned ON, Where the document has 20 versions. So, If I Set the versioning limit to 5, will it delete the Older 15 versions and Keep only the last 5? NO NO NO, Until we create a new document or edit the existing document, those versioning limits will not be applicable. This new limit will not affect the existing old version. We need to Delete them explicitly.
Take a Look at this task list, where I've limited the versions NOW to 3, But it has existing older versions!
Programmatically delete old versions with PowerShell
So, To clean up the existing versions, Let's seek help from PowerShell again! Let the PowerShell delete older versions.
When you have a large number of versions in the SharePoint list, iterating through versions may result in performance hits. So, the alternate method goes below:
Update: I've created a utility to limit and cleanup old versions of documents. You can download it here: SharePoint Versioning Manager - Control Versioning Settings & Clean-Up Old Versions
On analyzing the site space figured out: For a 1GB site, versions are occupying nearly 300MB!!! So, I wanted to clean-up the versions except for the last 5 minor/Last 5 Major. Oh, Yeah, to set versioning limit in SharePoint, Just get into the List/Library settings > Versioning settings then setup the versioning limits.
Quite simple, Isn't it? Ah, but the user has 100+ libraries where unlimited number of versions enabled! OMG!!!
Limit number of versions in SharePoint with PowerShell
PowerShell comes to rescue again! Here is the code to delete the older versions, except the last 5 major and minor.
$SPsiteCollection = Get-SPSite "http://SharePointSite.com" # Loop through all Webs in the Site Collection foreach($SPweb in $SPsiteCollection.AllWebs) { #loop through all lists in web foreach ($SPlist in $SPweb.Lists) { if($SPlist.EnableVersioning -eq $true) { write-host "Setting versioning Limit for :" $SPlist.title $SPlist.MajorVersionLimit = 5; # To Disable Versioning use: $SPlist.EnableVersioning=$false # To Enable Minorversion: $SPlist.EnableMinorVersions = $true; # Minor version Limit: $SPlist.MajorWithMinorVersionsLimit = 5; $SPlist.Update(); } } }How to Disable Versioning in a SharePoint List?
In case, You want to disable version history for a particular list or library, use this PowerShell script:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue #Define variables $WebURL="http://sharepoint.crescent.com" $ListName="Projects" #Get the web and List $web = Get-SPWeb $WebURL $List = $web.Lists[$ListName] #Disable Versioning $List.EnableVersioning = $false $List.Update() #Delete all existing versions of all list items ForEach($item in $list.Items) { $item.URL; $item.SystemUpdate(); }
Ok, What about cleaning the Old versions?
I have set-upped versioning limits, Will it delete the older version beyond my limit? unfortunately "NO"
Say for e.g. I have a Document in Document Library with an unlimited number of versions turned ON, Where the document has 20 versions. So, If I Set the versioning limit to 5, will it delete the Older 15 versions and Keep only the last 5? NO NO NO, Until we create a new document or edit the existing document, those versioning limits will not be applicable. This new limit will not affect the existing old version. We need to Delete them explicitly.
Take a Look at this task list, where I've limited the versions NOW to 3, But it has existing older versions!
Programmatically delete old versions with PowerShell
So, To clean up the existing versions, Let's seek help from PowerShell again! Let the PowerShell delete older versions.
$SPweb = Get-SPWeb "http://SharePointSite.com" $versionsToKeep =5; $SPlist = $SPweb.Lists["Tasks"] foreach ($SPitem in $SPlist.Items) { $currentVersionsCount= $SPItem.Versions.count if($currentVersionsCount -gt $versionstoKeep) { for($i=$currentVersionsCount-1; $i -gt $versionstoKeep; $i--) { $SPItem.versions[$i].delete() } } }Alternatively, You can perform an empty update in list items to apply the new versioning limit and cleanup older versions.
$SPweb = Get-SPWeb "http://sharepoint.crescent.com" $versionsToKeep =3; $SPlist = $SPweb.Lists["Tasks"] foreach ($SPListItem in $SPlist.Items) { $currentVersionsCount= $SPListItem.Versions.count if($currentVersionsCount -gt $versionstoKeep) { $SPListItem.SystemUpdate() } }
When you have a large number of versions in the SharePoint list, iterating through versions may result in performance hits. So, the alternate method goes below:
#Variables for Processing $WebURL = "http://sharepoint.crescent.com/operations/imphilippineswksp/QII/" $ListName ="Project Cost" $ItemID="512" #Get the Web and List objects $web = Get-SPWeb($WebURL) $list = $web.Lists[$ListName] #Set list version setting $list.MajorVersionLimit = 10 $list.Update() #Get the List Item $item = $list.GetItemById($itemId) #Perform a empty update - without creating new version, so that versioning changes will take effect $item.SystemUpdate($false) write-host "Total Number of versions Now:"$Item.Versions.count #Dispose $web.dispose();
Update: I've created a utility to limit and cleanup old versions of documents. You can download it here: SharePoint Versioning Manager - Control Versioning Settings & Clean-Up Old Versions
How will be the script for minor versions?
ReplyDeleteYou can set List.EnableMinorVersions and list.MajorWithMinorVersionsLimit properties.
DeleteShouldn't the line:
ReplyDeletefor($i=$currentVersionsCount-1; $i -gt $versionstoKeep; $i--)
Instead be:
for($i=$currentVersionsCount-$versionstoKeep; $i -gte 1; $i--)
For instance, if there are 20 versions and you want to keep 5 this would start with version 15 and delete older versions (lower number versions) through version 1.
It seems the line you used would delete all but the oldest 5. Am I reading it wrongly?
Hi there,
DeleteThe above code aims to keep the latest versions and delete the old one. Versions are stored as First-in-first-out.
For the 2016-version, it seems that the:
Deletefor($i=$currentVersionsCount-$versionstoKeep; $i -gte 1; $i--)
is the correct code..
When I try to delete old versions, getting the below error. Any idea.
ReplyDeleteYou cannot call a method on a null-valued expression.
At E:\test\Vers_del.ps1:53 char:53
+ $Item.Versions[770.0].delete <<<< ()
+ CategoryInfo : InvalidOperation: (delete:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Had to tweek a couple of things, but this saved me days of work. Thanks a bunch!
ReplyDeleteNote, the equal sign = is a assignment in powershell for genuine comparison operations you need -eq. This line: if($SPlist.EnableVersioning=$true) will always be true. Needs to be if($SPlist.EnableVersioning -eq $true)
ReplyDeleteIs there a table or list where the version information is stored and if so do you know the URL?
ReplyDeleteHow can I use the script (Alternatively, You can perform an empty update in list items to apply new versioning limit and cleanup older versions) in Sharepoint-Online?
ReplyDeleteHere is the Script to limit-cleanup version history: SharePoint Online: Delete Version History using PowerShell CSOM
Deleteinteresting power shell script would it be possibel to make a script where you can define the number of versions and when reached that level it will automatically delete the oldest version and ad the newest.
ReplyDeleteA rule like First one in last one out :) this would be very functional and very handy .
Any ideas some one ?
$item.SystemUpdate() is not able to reflect the changes to items in the library. Any other suggestion as I have to implement this setting to all the libraries in my farm
ReplyDeleteThis is a great script - thanks for sharing! After running for a large Web Application, I'm seeing the overall size reduced around 250GB (using Microsoft's SMAT); however, the content DB is only showing about 50GB free space. Do you know why I wouldn't see the size reduction reflected in the Content DB?
ReplyDeleteWell, If you have deleted the versions or performed update operation after setting up new versioning limits, that should gain you free space. After a massive delete/cleanup operations, it's a good idea to defrag the database and do log cleanup.
Delete