Deleting versions of large SharePoint files using an undocumented Microsoft Graph operation

Deleting versions of large SharePoint files using an undocumented Microsoft Graph operation

Last updated on May 11, 2026

A customer contacted me because they were running out of storage space on SharePoint Online. Apparently, one team had decided to store database files in a SharePoint document library, causing the site to grow to 3,5 terabytes. Now, the database files were going to be moved to Azure by another contractor, but the limited SharePoint Online storage space was causing daily struggles, so in the meantime, I was asked if there was anything I could do to immediately ease the situation.

A file size in SharePoint is not the same as the size of the latest version of a file in a document library. The total size of a document is larger because it also includes the prior versions of the file. By default, SharePoint stores the last 500 versions of a file. So you can probably imagine how humongous file sizes we were talking about when these database files stored in a SharePoint document library could have several hundred versions.

The problem: deleting versions for large files

Deleting hundreds of old versions for hundreds of documents manually would have been a huge endeavour, so I looked into automating the task. We agreed with the customer that the processing should target only the database files and that the latest 10 versions of each document should be retained, just in case.

With these requirements in mind, I proceeded to write a PowerShell script to perform the task. At first, I looked at the following commandlets available in the PnP.PowerShell module.

  • Get-PnPFileVersion: Retrieves the previous versions of a file (i.e., does not retrieve the current/latest version of the file)
  • Remove-PnPFileVersion: Removes the specified version

I wrote the script so that it’d fetch all files in the document library, filter them by file extension, then loop through them, first fetching the previous versions and then deleting all but the latest 9 (since the current version wasn’t included). But when I ran the script, I immediately got the following error when it came time to delete a version:

Operation is not valid due to the current state of the object.

Apparently, the Remove-PnPFileVersion does not support deleting individual versions for files larger than 2 GB. OK, so what other options do we have?

Next, I decided to try CSOM. However, that command also gave me the same error. What about the SharePoint Online REST API? You guessed it, received the same error again.

The solution: an undocumented Microsoft Graph operation

Microsoft Graph has some operations related to file versions. In the API reference documentation, there are List, Get, Restore, and Download operations for drive item versions. According to the documentation, there’s no operation that allows deleting file versions. But I decided to give it a shot anyway.

So, I crafted an HTTP request similar to the “get individual file version” operation, but this time I changed the HTTP method from GET to DELETE. And lo and behold: it worked like a charm!

After discovering this, I also switched the “get file versions” part of my code to use Microsoft Graph, so I’d get all file versions rather than all except for the latest, which made my script’s version retention logic easier to follow. The delete operation can’t be used to delete the current version, so I didn’t need to worry about accidentally doing so. I did try, though, just to see what’d happen, and the operation gave me an error.

I won’t include the entire script I wrote for my customer here, but below is an example script snippet that retrieves all versions of a file, lets you filter them for deletion based on your criteria, and finally deletes the versions that remain after filtering. All by using Microsoft Graph via the PnP.PowerShell module. Enjoy!

Afterword

In the end, my script removed over 2 TB worth of old versions, so the customer was very happy. So, what did we learn here? Even though Microsoft Graph documentation doesn’t list an operation for an entity, that doesn’t necessarily mean it doesn’t exist. It’s always good to have that kind of “hacker mentality” and to practice working around the restrictions. You never know what’s truly possible before you give it a go!

I hope you found this blog post useful. If you’d like to read more articles written by me and get notified when they get published, feel free to subscribe to my blog and/or follow me on LinkedIn. You can find controls for both in the sidebar or at the bottom of the mobile view.

Happy coding and until next time!

Laura



Leave a Reply

Your email address will not be published. Required fields are marked *