My customer has a Page Library with versioning enabled and no versions limit.

There is pages with more than 300.000 versions.

I need to delete all old versions, but keep safe the 5 newer versions.

We have a On-Premises solution. My first try was calling SPFile.Versions.DeleteAll() with no success after 1 day running it in just one file.

My next try was to limit library versions count to 5 and then running SPFile.Item.SystemUpdate() having the same result as above.

And then, by last, I created a TestPage.aspx file with some versions. I believed that my rescue would be the SPWeb.ProcessBatchData method and so confident as I could be, I wrote...

<?xml version="1.0" encoding="UTF-8"?> 
<ows:Batch OnError="Continue">
    <Method ID="0,Delete">
      <SetList Scope="Request">xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</SetList>
      <SetVar Name="Cmd"> Delete </SetVar>
      <SetVar Name="ID"> 21 </SetVar>
      <SetVar Name="owshiddenversion"> 2 </SetVar> 
      <SetVar Name="owsfileref"> http://customer/Pages/TestPage.aspx </SetVar>

And SPWeb.ProcessBatchData method has deleted TestPage.aspx and all its versions.

What could I do to delete several versions of several files in several lists without taking more than one day per file or loosing all data?

I think SPWeb.ProcessBatchData is the answer, but I missing something here.

1 Answer 1


If it is SharePoint 2013, you can trim the versions using JavaScript. Below is the code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<html xmlns="http://www.w3.org/1999/xhtml">
        <script type="text/javascript">
            function AddTrimmerIcon() {
                $(".ms-qcb-root ul li:nth-child(4)").each(function() {
                    $(this).first().before('<li class="ms-qcb-item">' +
                    '<button class="ms-qcb-button ms-qcb-buttons-alignmentfix
                    js-listview-qcbUploadButton js-callout-body js-qcb-button ms-qcb-glyph"
                    type="button"' +
                    'title="Select file and trim versions of the file" role="button"
                    accesskey="t" onclick="TrimDocument()"><span class="ms-qcb-glyph
                    ms-listview-glyph-withmargin ms-listview-sync-glyph
                    ms-core-form-heading"><img style="height:20px;width:25px;" src="' +
                    _spPageContextInfo.webServerRelativeUrl +
            function TrimDocument() {
                SP.SOD.executeFunc('sp.js', 'SP.ClientContext', Trim);
            function Trim() {
                var count = SP.ListOperation.Selection.getSelectedItems(ctx).length;
                if (count == 0) {
                    alert("Please select an item from the list");
                    return false;
                if (count > 1) {
                    alert("Please select only one file");
                    return false;
                SP.UI.ModalDialog.showWaitScreenWithNoClose('Trimming Versions', 'Please wait while
                the versions of the file are being deleted');
                var title = ctx.ListTitle;
                var items = SP.ListOperation.Selection.getSelectedItems(ctx);
                //get file versions
                    url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('" + title
                    + "')/items(" + items[0].id + ")/File/Versions",
                    method: "GET",
                    headers: {
                        "Accept": "application/json; odata=verbose"
                    success: function(data) {
                        var totalversions = data.d.results.length;
                        $.each(data.d.results, function(index, item) {
                            var count = index;
                                url: _spPageContextInfo.webAbsoluteUrl +
                                "/_api/web/lists/getByTitle('" + title + "')/items(" + items[0].id
                                + ")/File/Versions('" + item.ID + "')",
                                type: "POST",
                                contentType: "application/json;odata=verbose",
                                headers: {
                                    "Accept": "application/json;odata=verbose",
                                    "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                                    "X-HTTP-Method": "DELETE",
                                    "IF-MATCH": "*"
                                success: function(data) {
                                    if (totalversions == (count + 1)) {
                                error: function(data) {
                    error: function(data) {


  • I cant use the rest query /_api/Web/Lists/getByTitle(TITLE)/items(ID)/File/Versions because 300.000 versions is A LOT versions. My query not even returns... In addition, doing an POST for each version is insane. To delete this massive collection, only SSOM could. Jan 9, 2017 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.