Set all Onedrive file Versions back one version

Joshua Smith 1 Reputation point
2021-09-20T08:43:01.847+00:00

I have a client where most of their files in Onedrive are corrupt. I found that each of these corrupt files has 2 versions and restoring it back to the earlier version restores the file. The issue I am facing is that due to the sheer volume of files it would take an eternity to restore each file by hand, as well as I can restore the whole Onedrive back as the client has already made changes and cant lose them.

I reached out to Microsoft 365 support and they gave me the below script to run, which sets the version back for the entire SharePoint site(personal onedrive site). however, I get the following error:

Failed to load files in Documents, Exception calling “ExecuteQuery” with “0” argument(s): “The attempted operation is prohibited because it exceeds the list view threshold enforced by the administrator.”

Script:

#Import SharePoint Online module
Import-Module Microsoft.Online.SharePoint.Powershell

Function Restore-PreviousVersion()
{
  param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $ListName
    )
   Try {
        $Cred= Get-Credential
        $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)

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

        #Get all items from the list/library
        $Query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery()
        $List = $Ctx.Web.Lists.GetByTitle($ListName)
        $Ctx.Load($List)
        $ctx.ExecuteQuery()
        Write-Host "Total number of Items Found in the list:" $List.ItemCount
        $ListItems = $List.GetItems($Query)
        $Ctx.Load($ListItems)
        Write-Host "Loaded ListItems into Context"
        $Ctx.ExecuteQuery()
        Write-Host "Excecuted Context Query"

        #Iterate through each item and restore the previous version
        Foreach($Item in $ListItems)
        { 
            #Get the file versions
            $File = $Ctx.Web.GetFileByServerRelativeUrl($Item["FileRef"])
            $Ctx.Load($File)
            $Ctx.Load($File.Versions)
            $Ctx.ExecuteQuery()

            If($File.Versions.Count -gt 0)
            {
                #Get the previous version's label
                $VersionLabel=$File.Versions[($File.Versions.Count-1)].VersionLabel

                #Restore the previous version
                $File.Versions.RestoreByLabel($VersionLabel)
                $Ctx.ExecuteQuery()
                Write-Host -f Green "Previous version $VersionLabel Restored on :" $Item["FileRef"]
            }
            Else
            {
                Write-host "No Versions Available for "$Item["FileRef"] -f Yellow
            }
        }
     }
    Catch {
        write-host -f Red "Error Removing User from Group!" $_.Exception.Message
    }
} 

#Set parameter values
$SiteURL="<Site_URL>"
$ListName="Documents"

#Call the function to restore previous document version
Restore-PreviousVersion -SiteURL $SiteURL -ListName $ListName

This is on office 365 SharePoint and I can't change the value. Microsoft support has said they cannot assist me as this requires custom scripting. Can anyone advise how I can go about doing this? unfortunately, my PowerShell scripting skills are very limited.

Microsoft 365 and Office | SharePoint | For business | Windows
Microsoft 365 and Office | OneDrive | For business | Windows
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. MichaelHan-MSFT 18,126 Reputation points
    2021-09-21T08:26:51.35+00:00

    Hi @Joshua Smith ,

    The list view threshold error usually happens if you have more than 5000 items/files in the document library.

    You could try to get the listitems in batch as the below:

     #Import SharePoint Online module  
     Import-Module Microsoft.Online.SharePoint.Powershell  
           
     Function Restore-PreviousVersion()  
     {  
       param  
         (  
             [Parameter(Mandatory=$true)] [string] $SiteURL,  
             [Parameter(Mandatory=$true)] [string] $ListName  
         )  
        Try   
        {  
             $Cred= Get-Credential  
             $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)  
           
             #Setup the context  
             $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)  
             $Ctx.Credentials = $Credentials  
                   
             $List = $Ctx.Web.Lists.GetByTitle($ListName)  
             $Ctx.Load($List)  
             $ctx.ExecuteQuery()  
      
                 #Define Query to get List Items in batch  
             $Query = New-Object Microsoft.SharePoint.Client.CamlQuery  
             $Query.ViewXml = @"  
             <View Scope='RecursiveAll'>  
                <Query>  
                    <OrderBy><FieldRef Name='ID' Ascending='TRUE'/></OrderBy>  
                </Query>  
                <RowLimit Paged="TRUE">2000</RowLimit>  
            </View>  
    "@  
                #Get List Items in Batch  
        Do  
        {  
            $ListItems = $List.GetItems($Query)  
            $Ctx.Load($ListItems)  
            $Ctx.ExecuteQuery()  
            $ListItems.count  
            $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition  
                     #Iterate through each item and restore the previous version  
            Foreach($Item in $ListItems)  
            {   
                #Get the file versions  
                $File = $Ctx.Web.GetFileByServerRelativeUrl($Item["FileRef"])  
                $Ctx.Load($File)  
                $Ctx.Load($File.Versions)  
                $Ctx.ExecuteQuery()  
           
                If($File.Versions.Count -gt 0)  
                {  
                    #Get the previous version's label  
                    $VersionLabel=$File.Versions[($File.Versions.Count-1)].VersionLabel  
           
                    #Restore the previous version  
                    $File.Versions.RestoreByLabel($VersionLabel)  
                    $Ctx.ExecuteQuery()  
                    Write-Host -f Green "Previous version $VersionLabel Restored on :" $Item["FileRef"]  
                }  
                Else  
                {  
                    Write-host "No Versions Available for "$Item["FileRef"] -f Yellow  
                }  
            }  
        }  
        While($Query.ListItemCollectionPosition -ne $null)  
        }  
         Catch {  
             write-host -f Red "Error Getting List Items:" $_.Exception.Message  
         }  
     }   
           
     #Set parameter values  
     $SiteURL="<Site_URL>"  
     $ListName="Documents"  
           
     #Call the function to restore previous document version  
     Restore-PreviousVersion -SiteURL $SiteURL -ListName $ListName  
    

    If an Answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. MichaelHan-MSFT 18,126 Reputation points
    2021-09-23T09:54:48.807+00:00

    @Joshua Smith ,
    It could be that there are also some folders in your library. You could change the code to this:

       Function Restore-PreviousVersion()  
      {  
        param  
          (  
              [Parameter(Mandatory=$true)] [string] $SiteURL,  
              [Parameter(Mandatory=$true)] [string] $ListName  
          )  
         Try   
         {  
              $Cred= Get-Credential  
              $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)  
               
              #Setup the context  
              $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)  
              $Ctx.Credentials = $Credentials  
                       
              $List = $Ctx.Web.Lists.GetByTitle($ListName)  
              $Ctx.Load($List)  
              $ctx.ExecuteQuery()  
          
                  #Define Query to get List Items in batch  
              $Query = New-Object Microsoft.SharePoint.Client.CamlQuery  
              $Query.ViewXml = @"  
              <View Scope='RecursiveAll'>  
                 <Query>  
                     <OrderBy><FieldRef Name='ID' Ascending='TRUE'/></OrderBy>  
                 </Query>  
                 <RowLimit Paged="TRUE">2000</RowLimit>  
             </View>  
    "@  
                 #Get List Items in Batch  
         Do  
         {  
             $ListItems = $List.GetItems($Query)  
             $Ctx.Load($ListItems)  
             $Ctx.ExecuteQuery()  
             $ListItems.count  
             $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition  
                      #Iterate through each item and restore the previous version  
             Foreach($Item in $ListItems)  
             {   
                 #Get the file version  
                 if($Item["File_x0020_Type"]){  
                 $File = $Ctx.Web.GetFileByServerRelativeUrl($Item["FileRef"])  
                 $Ctx.Load($File)  
                 $Ctx.Load($File.Versions)  
                 $Ctx.ExecuteQuery()  
               
                 If($File.Versions.Count -gt 0)  
                 {  
                     #Get the previous version's label  
                     $VersionLabel=$File.Versions[($File.Versions.Count-1)].VersionLabel  
               
                     #Restore the previous version  
                     $File.Versions.RestoreByLabel($VersionLabel)  
                     $Ctx.ExecuteQuery()  
                     Write-Host -f Green "Previous version $VersionLabel Restored on :" $Item["FileRef"]  
                 }  
                 Else  
                 {  
                     Write-host "No Versions Available for "$Item["FileRef"] -f Yellow  
                 }  
                 }  
             }  
         }  
         While($Query.ListItemCollectionPosition -ne $null)  
         }  
          Catch {  
              write-host -f Red "Error Getting List Items:" $_.Exception.Message  
          }  
      }   
         
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.