Restoring Previous Versions of Items in a SharePoint List Using PnP PowerShell
When working with SharePoint lists, there might be times when you need to restore items to a previous version. Whether it’s due to an error, unwanted changes, or simply needing to revert to an earlier state, SharePoint’s versioning feature is a lifesaver. I used the script to undo bulk changes made by a Power Automate flow after the process failed halfway due to some data needing correction. For data integrity, the bulk update needed to be undone before running the Power Automate flow again after the data corrections were made.
This posts covers how to restore previous versions of items in a SharePoint list using PnP PowerShell
.
PowerShell Script
Below is a sample script which retrieves data based on a condition and checked whether a version was created on a particular date by the system account as a result of automation process and restore a previous version of the list item. Amend the script as per your requirements.
The cmdlet Restore-PnPListItemVersion
below does the trick to restore the previous version of an item by substracting 1 from the item property VersionLabel
.
Restore-PnPListItemVersion -List $List -Identity $itemId -Version ($_.VersionLabel - 1).ToString(".0") -Force
The whole sample script is below. Ensure to install PnP PowerShell and have access to the SharePoint List.
# array to save items that have been restored | |
$ItemsRestored = [System.Collections.ArrayList]@(); | |
function Restore-PreviousVersions { | |
Param( | |
[Parameter(Mandatory = $true)][string] $List, | |
[Parameter(Mandatory = $true)][string] $Key, | |
[Parameter(Mandatory = $true)][string] $User, | |
[Parameter(Mandatory = $true)][string] $Date | |
) | |
# Ensure the columns referenced in the CAML query are indexed, otherwise you will get the listview threshold error if there are more than 5000 items in the list. | |
$query = @" | |
<View> | |
<Query> | |
<Where> | |
<Eq><FieldRef Name='Key' /><Value Type='Text'>$Key</Value></Eq> | |
</Where> | |
</Query> | |
<ViewFields> | |
<FieldRef Name='Id' /> | |
</ViewFields> | |
</View> | |
"@ | |
$counter = 0 | |
$items = Get-PnPListItem -List $List -Query $query | Select-Object Id, ObjectVersion | |
$items | ForEach-Object { | |
if ($_.ObjectVersion -ne 1) { | |
$listVersions = Get-PnPListItemVersion -List $List -Identity $_.Id | |
$itemId = $_.Id | |
if ($listVersions) { | |
if ($listVersions.Count -gt 1) { | |
$listVersions | ForEach-Object { | |
if ($_.Values.Editor.LookupValue -eq $User -and $_.Created.ToString("yyyy-MM-dd") -eq $Date) { | |
$informationMessage = "Edited by $($_.Values.Editor.LookupValue) on list $List with ID $itemId on $($_.Created.ToString("yyyy-MM-dd")) with version $($_.VersionLabel)" | |
Write-Host $informationMessage -ForegroundColor Yellow | |
Restore-PnPListItemVersion -List $List -Identity $itemId -Version ($_.VersionLabel - 1).ToString(".0") -Force | |
$informationMessage = "Restored item $itemId to version $(($_.VersionLabel - 1).ToString(".0")) for filter $Key." | |
Write-Host $informationMessage -ForegroundColor Yellow | |
$ItemsRestored.Add([PSCustomObject]@{ | |
ItemId = $itemId | |
List = $List | |
RestoredVersion = ($_.VersionLabel - 1).ToString(".0") | |
FilterKey = $Key | |
}) | |
$counter += 1 | |
} | |
} | |
} | |
} | |
} | |
} | |
Write-Host "Total items updated on $List - $counter for $Key" -ForegroundColor Yellow | |
} | |
Start-Transcript | |
# Generate a unique log file name using today's date and time | |
$todayDate = Get-Date -Format "yyyy-MM-dd_HHmm" | |
$restoredVersion = "restored-file-versions_$todayDate.csv" | |
$restoredVersionFilePath = Join-Path -Path $PSScriptRoot -ChildPath $restoredVersion | |
# Tenant URL | |
$siteUrl = Read-Host -Prompt "Enter site collection URL" | |
Connect-PnPOnline -Url $siteUrl -Interactive | |
$PaymentsList = "Payments" | |
Restore-PreviousVersions -List $PaymentsList -Key "202407-Ms-Software" -User "System Account" -Date "2024-07-13" | |
$ItemsRestored | Export-Csv -Path $restoredVersionFilePath -NoTypeInformation -Force -Delimiter "," | |
Stop-Transcript |
An example of the output: