SharePoint Online: Delete Version History using PowerShell

The versioning feature in SharePoint Online allows you to access previous copies of a document or list items. By default, versioning is enabled on your SharePoint Online document libraries. When a user makes edits, SharePoint automatically creates a new version with metadata such as created by, Timestamps, etc.

How to Delete Version History in SharePoint Online?

To delete all previous versions of a document in SharePoint, follow these steps:

  • Navigate to your SharePoint Library, select the file and then click on “Version History” from the ribbon menu.sharepoint online delete version history
  • From the version history page, click on the “Delete all versions” link, confirm if prompted!sharepoint online delete versions

SharePoint Online: Delete Version History using PowerShell

You may delete all versions of a document or leave the latest ‘N’ number of versions and then delete the rest. Here is my PowerShell scripts to delete versions in SharePoint Online:

Case 1: Delete All Versions for a particular file:

This PowerShell script deletes all versions in SharePoint Online.

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
  
#Config Parameters
$SiteURL= "https://crescent.sharepoint.com/sites/sales/"
$FileURL="/Sites/Sales/ProjectDocuments/ProjectMetrics.xlsx"

#Setup Credentials to connect
$Cred = Get-Credential
$Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName,$Cred.Password)

Try {
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = $Cred

    #Get the File
    $File = $Ctx.Web.GetFileByServerRelativeUrl($FileURL)

    #Get all versions of the file
    $Versions = $File.Versions
    $Ctx.Load($Versions)
    $Ctx.ExecuteQuery()

    Write-host -f Yellow "Total Number of Versions Found :" $Versions.count

    #Delete all versions of the file
    $Versions.DeleteAll()
    $Ctx.ExecuteQuery()

    Write-host -f Green "All versions Deleted for given File!"   
}
Catch {
    write-host -f Red "Error deleting versions!" $_.Exception.Message
}

Case 2: Delete All Versions for All Files in a Library:

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
   
#Config Parameters
$SiteURL= "https://crescent.sharepoint.com/"
$LibraryName="Project Docs"
 
#Setup Credentials to connect
$Cred = Get-Credential
$Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName,$Cred.Password)
 
Try {
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = $Cred
 
    #Get the web and Library
    $Web=$Ctx.Web
    $List=$web.Lists.GetByTitle($LibraryName)
  
    #Get all List items from the library - Exclude "Folder" objects
    $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
    $Query.ViewXml="<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='FSObjType'/><Value Type='Integer'>0</Value></Eq></Where></Query></View>"
    $ListItems = $List.GetItems($Query)
    $Ctx.Load($ListItems)
    $Ctx.ExecuteQuery()  
   
    #Loop through each file in the library
    Foreach($Item in $ListItems)
    {       
        #Get all versions of the file
        $Ctx.Load($Item.File)        
        $Ctx.Load($Item.File.Versions)
        $Ctx.ExecuteQuery()
        Write-host "Processing Item:" $Item.file.Name
 
        #Delete all versions of the file
        If($Item.File.Versions.count -gt 0)
        {
            $Item.File.Versions.DeleteAll()
            $Ctx.ExecuteQuery()
            Write-host -f Green "All Versions deleted on "$Item.file.Name
        }
    }    
}
Catch {
    write-host -f Red "Error Deleting version History!" $_.Exception.Message
}

Case 3: Leave Last Five versions and Delete the Rest in the Library:

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
  
#Config Parameters
$SiteURL= "https://crescent.sharepoint.com/sites/sales/"
$LibraryName="Project Documents"
$VersionsToKeep=5

#Setup Credentials to connect
$Cred = Get-Credential
$Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName,$Cred.Password)

Try {
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = $Cred
  
    #Get the web and Library
    $Web=$Ctx.Web
    $List=$web.Lists.GetByTitle($LibraryName)
 
    #Get all items from the library
    $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
    $Query.ViewXml="<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='FSObjType'/><Value Type='Integer'>0</Value></Eq></Where></Query></View>"
    $ListItems = $List.GetItems($Query)
    $Ctx.Load($ListItems)
    $Ctx.ExecuteQuery()
 
    #Loop through each file in the library
    Foreach($Item in $ListItems)
    {
        #Get all versions of the file
        $Versions = $Item.File.Versions
        $Ctx.Load($Versions)
        $Ctx.Load($Item.File) #To get File Name
        $Ctx.ExecuteQuery()

        Write-host -f Yellow "Total Number of Versions Found in '$($Item.File.Name )' : $($Versions.count)"

            #Check if number of versions are more than limit
            While($Item.File.Versions.Count -gt $VersionsToKeep)
            {
                write-host "Deleting Version:" $Versions[0].VersionLabel
                $Versions[0].DeleteObject()
                $Ctx.ExecuteQuery()
    
                #Reload versions
                $Ctx.Load($Item.File.Versions)
                $Ctx.ExecuteQuery()
            }
    }
}
Catch {
    write-host -f Red "Error deleting versions!" $_.Exception.Message
}

If you want to keep last five versions and delete the rest for a particular file, use:

    #Get the File
    $File = $Ctx.Web.GetFileByServerRelativeUrl($FileURL)

    #Get all versions of the file
    $Versions = $File.Versions
    $Ctx.Load($Versions)
    $Ctx.ExecuteQuery()
    $Versionscount = $Versions.count

    Write-host -f Yellow "Total Number of Versions Found :" $Versionscount

    #Check if number of versions are more than limit
    While($File.Versions.Count -gt $VersionsToKeep)
    {
        write-host "Deleting Version:" $Versions[0].VersionLabel
        $Versions[0].DeleteObject()
        $Ctx.ExecuteQuery()
    
        #Reload versions
        $Ctx.Load($File.Versions)
        $Ctx.ExecuteQuery()
    }

To delete a particular version by its Label, use: $Versions.DeleteByLabel($LabelID) 

You can also delete versions in SharePoint Online using PnP PowerShell: SharePoint Online: Delete Version History using PnP PowerShell

Salaudeen Rajack

Salaudeen Rajack is a SharePoint Architect with Two decades of SharePoint Experience. He loves sharing his knowledge and experiences with the SharePoint community, through his real-world articles!

15 thoughts on “SharePoint Online: Delete Version History using PowerShell

  • May 20, 2021 at 4:26 PM

    $file.versions.count is not displaying the correct count. Its showing one less than the actual count. In the above screenshot there are 11 versions but $file.versions.count is showing 10. Can you please help?

    Reply
  • April 21, 2021 at 12:03 AM

    This would be a huge help – but I’m getting an error. When I merge this script with the Do/While for large lists I am receiving an error Error deleting versions! Cannot find an overload for “Load” and the argument count: “1”. Any suggestions?

    Reply
  • January 31, 2021 at 11:49 AM

    Hello. Thank you for this, it has helped enormously. I have some libraries that exceed the 5000 file limit and am unsure how to integrate the batch process into Case 2. Is that something you could help with please? Thanks

    Reply
  • March 22, 2019 at 10:14 PM

    Can you please share the script to keep top 5 versions and delete all else, to run it in PowerShell usinf PnP ?

    Reply
  • October 19, 2018 at 6:39 PM

    I am getting an Error that I do not know how to fix……..could someone help: — Error deleting versions! Exception calling “ExecuteQuery” with “0” argument(s): “Cannot invoke method or retrieve property from null object. Object returned by the following call stack is null. “File

    Reply
    • October 22, 2018 at 4:33 PM

      Salaudeen, Thanks for your quick. This is very helpful but I think many of us need help as our users keep adding files to multiple folders. Is possible to add a script targeting a specific folder and set it up as part of the variables. I believer We have admins here with multiple folders as me with more than 1000 items and set up to 2 or 3 versions that we are trying to keep “LEAN”……..if Possible We will Appreciate the help.

      Reply
    • October 23, 2018 at 1:37 PM

      Simple! Just append this line after line#25 in the case 3:
      $Query.FolderServerRelativeUrl=”/Project Docs/Active” (or whatever sub-folder path)

      Reply
    • November 1, 2018 at 7:39 PM

      This comment has been removed by the author.

      Reply
  • October 10, 2018 at 7:50 AM

    Does Case 2 cover all files in all folders? and is it possible to have it filtered to limit rows to 5000 on large sites ?
    Thanks !

    Reply
  • March 27, 2018 at 8:53 PM

    Hi Salaudeen,
    These are really great and helpful scripts.
    I’m using the script to delete all but 5 versions for all files in a library, but the script fails if the library has any sub-folders. Any ideas what could be added so that the sub-folders are ignored? Thanks!

    Reply

Leave a Reply