SharePoint Online: Version History Report using PowerShell
Requirement: Generate version history report for all sites in a SharePoint site collection.
SharePoint Online PowerShell to Get Version History Details of a Document Library
The version history feature in SharePoint Online maintains a history of all changes made to any file or list item. When multiple users are working on a document, you may have to audit version history to view or restore previous versions of a document. In this article, we will see how to generate a version history report for SharePoint Online using PowerShell.
#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"
#Set Parameters
$SiteURL="https://Crescent.sharepoint.com/sites/marketing"
$LibraryName="Branding"
$ReportOutput = "C:\Temp\VersionHistoryRpt.csv"
Try {
#Setup Credentials to connect
$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 the web & Library
$Web=$Ctx.Web
$Ctx.Load($Web)
$List = $Web.Lists.GetByTitle($LibraryName)
$Ctx.ExecuteQuery()
#Query to Batch process Items from the document library
$Query = New-Object Microsoft.SharePoint.Client.CamlQuery
$Query.ViewXml = "<View Scope='RecursiveAll'><Query><OrderBy><FieldRef Name='ID' /></OrderBy></Query><RowLimit>2000</RowLimit></View>"
Do {
$ListItems=$List.GetItems($Query)
$Ctx.Load($ListItems)
$Ctx.ExecuteQuery()
$Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
$VersionHistoryData = @()
#Iterate throgh each file - Excluding Folder Objects
Foreach ($Item in $ListItems | Where { $_.FileSystemObjectType -eq "File"})
{
$File = $Web.GetFileByServerRelativeUrl($Item["FileRef"])
$Ctx.Load($File)
$Ctx.Load($File.ListItemAllFields)
$Ctx.Load($File.Versions)
$Ctx.ExecuteQuery()
Write-host -f Yellow "Processing File:"$File.Name
If($File.Versions.Count -ge 1)
{
#Calculate Version Size
$VersionSize = $File.Versions | Measure-Object -Property Size -Sum | Select-Object -expand Sum
If($Web.ServerRelativeUrl -eq "/")
{
$FileURL = $("{0}{1}" -f $Web.Url, $File.ServerRelativeUrl)
}
Else
{
$FileURL = $("{0}{1}" -f $Web.Url.Replace($Web.ServerRelativeUrl,''), $File.ServerRelativeUrl)
}
#Send Data to object array
$VersionHistoryData += New-Object PSObject -Property @{
'File Name' = $File.Name
'Versions Count' = $File.Versions.count
'File Size' = ($File.Length/1KB)
'Version Size' = ($VersionSize/1KB)
'URL' = $FileURL
}
}
}
} While ($Query.ListItemCollectionPosition -ne $null)
#Export the data to CSV
$VersionHistoryData | Export-Csv $ReportOutput -NoTypeInformation
Write-host -f Green "Versioning History Report has been Generated Successfully!"
}
Catch {
write-host -f Red "Error Generating Version History Report!" $_.Exception.Message
}
PowerShell to Generate Version History Report for SharePoint Online Site Collection:
Here is the PowerShell to get the version history of all files in document libraries in a SharePoint Online site collection.
#Import SharePoint Online module
Import-Module Microsoft.Online.SharePoint.Powershell
Function Generate-VersionHistoryReport()
{
param
(
[Parameter(Mandatory=$true)] [string] $SiteURL,
[Parameter(Mandatory=$true)] [string] $ReportOutput
)
Try {
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credentials
#Get all subsites and Lists from the site
$Web = $Ctx.Web
$Ctx.Load($Web)
$Ctx.Load($Web.Webs)
$Lists = $Web.Lists
$Ctx.Load($Lists)
$Ctx.ExecuteQuery()
Write-host -f Yellow "Processing Site: "$SiteURL
#Exclude system lists
$ExcludedLists = @("Access Requests","App Packages","appdata","appfiles","Apps in Testing","Cache Profiles","Composed Looks","Content and Structure Reports","Content type publishing error log","Converted Forms",
"Device Channels","Form Templates","fpdatasources","Get started with Apps for Office and SharePoint","List Template Gallery", "Long Running Operation Status","Maintenance Log Library", ,"Master Docs","Master Page Gallery"
"MicroFeed","NintexFormXml","Quick Deploy Items","Relationships List","Reusable Content","Reporting Metadata", "Reporting Templates", "Search Config List","Site Assets", "Site Pages", "Solution Gallery",
"Style Library","Suggested Content Browser Locations","Theme Gallery", "TaxonomyHiddenList","User Information List","Web Part Gallery","wfpub","wfsvc","Workflow History","Workflow Tasks")
#Iterate through each list in a site and get versioning configuration
ForEach($List in $Lists)
{
if(($ExcludedLists -NotContains $List.Title) -and ($List.EnableVersioning) -and ($List.BaseType -eq "DocumentLibrary"))
{
Write-Host "`tProcessing Library:"$List.Title
#Query to Batch process Items from the document library
$Query = New-Object Microsoft.SharePoint.Client.CamlQuery
$Query.ViewXml = "<View Scope='RecursiveAll'><Query><OrderBy><FieldRef Name='ID' /></OrderBy></Query><RowLimit>2000</RowLimit></View>"
$VersionHistoryData = @()
Do {
$ListItems=$List.GetItems($Query)
$Ctx.Load($ListItems)
$Ctx.ExecuteQuery()
$Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
#Iterate throgh each version of file
$VersionHistoryData = @()
#Iterate throgh each file - Excluding Folder Objects
Foreach ($Item in $ListItems | Where { $_.FileSystemObjectType -eq "File"})
{
$File = $web.GetFileByServerRelativeUrl($Item["FileRef"])
$Ctx.Load($File)
$Ctx.Load($File.Versions)
$Ctx.ExecuteQuery()
If($File.Versions.Count -ge 1)
{
$VersionSize=0
#Calculate Version Size
Foreach ($Version in $File.Versions)
{
$VersionSize = $VersionSize + $Version.Size
}
#Send Data to object array
$VersionHistoryData += New-Object PSObject -Property @{
'Site' = $SiteURL
'Library' = $List.Title
'File Name' = $File.Name
'Version Count' = $File.Versions.count
'Version Size-KB' = ($VersionSize/1024)
'URL' = $SiteURL+$File.ServerRelativeUrl
}
}
}
} While ($Query.ListItemCollectionPosition -ne $null)
#Export the data to CSV
$VersionHistoryData | Export-Csv $ReportOutput -Append -NoTypeInformation
}
}
#Iterate through each subsite in the current web
Foreach ($Subweb in $Web.Webs)
{
#Call the function recursively to process all subsites underneaththe current web
Generate-VersionHistoryReport -SiteURL $Subweb.URL -ReportOutput $ReportOutput
}
}
Catch {
write-host -f Red "Error Generating version History Report!" $_.Exception.Message
}
}
#Set parameter values
$SiteURL="https://Crescent.sharepoint.com/sites/marketing"
$ReportOutput="C:\Temp\VersionHistoryRpt.csv"
#Get Credentials to connect
$Cred= Get-Credential
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
#Delete the Output report file if exists
If (Test-Path $ReportOutput) { Remove-Item $ReportOutput }
#Call the function to generate version History Report
Generate-VersionHistoryReport -SiteURL $SiteURL -ReportOutput $ReportOutput
This script produces a CSV file with data such as:
- Site
- Library
- File Name
- Number of Versions
- Version History Size
- URL of the document
If you want to export individual version details such as Version Label, Created by, comments, etc. use SharePoint Online: Export List Version History to Excel using PowerShell
PnP PowerShell to Get Version History Report on a Document Library
Here is the PnP PowerShell script to generate the version History report for a given site:
#Set Variables
$SiteURL = "https://crescent.sharepoint.com/sites/Marketing"
$LibraryName = "Documents"
$CSVPath = "C:\Temp\VersionHistoryRpt.csv"
#Connect to SharePoint Online site
Connect-PnPOnline -Url $SiteURL -Interactive
$VersionHistoryData = @()
#Iterate through all files
Get-PnPListItem -List $LibraryName -PageSize 500 | Where {$_.FieldValues.FileLeafRef -like "*.*"} | ForEach-Object {
Write-host "Getting Versioning Data of the File:"$_.FieldValues.FileRef
#Get FileSize & version Size
$FileSizeinKB = [Math]::Round(($_.FieldValues.File_x0020_Size/1KB),2)
$File = Get-PnPProperty -ClientObject $_ -Property File
$Versions = Get-PnPProperty -ClientObject $File -Property Versions
$VersionSize = $Versions | Measure-Object -Property Size -Sum | Select-Object -expand Sum
$VersionSizeinKB = [Math]::Round(($VersionSize/1KB),2)
$TotalFileSizeKB = [Math]::Round(($FileSizeinKB + $VersionSizeinKB),2)
#Extract Version History data
$VersionHistoryData+=New-Object PSObject -Property ([Ordered]@{
"File Name" = $_.FieldValues.FileLeafRef
"File URL" = $_.FieldValues.FileRef
"Versions" = $Versions.Count
"File Size (KB)" = $FileSizeinKB
"Version Size (KB)" = $VersionSizeinKB
"Total File Size (KB)" = $TotalFileSizeKB
})
}
$VersionHistoryData | Format-table -AutoSize
$VersionHistoryData | Export-Csv -Path $CSVPath -NoTypeInformation
Script Output:
Similarly, to generate the version history analysis for all libraries on the site, use this PowerShell script:
#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/vendors"
$CSVFile = "C:\Temp\VersionHistoryRpt.csv"
#Delete the Output report file if exists
If (Test-Path $CSVFile) { Remove-Item $CSVFile }
#Connect to SharePoint Online site
Connect-PnPOnline -Url $SiteURL -Interactive
#Get All Document Libraries from the Web - Exclude Hidden and certain lists
$ExcludedLists = @("Form Templates", "Preservation Hold Library","Site Assets", "Pages", "Site Pages", "Images",
"Site Collection Documents", "Site Collection Images","Style Library")
$Lists = Get-PnPList | Where-Object {$_.Hidden -eq $False -and $_.Title -notin $ExcludedLists -and $_.BaseType -eq "DocumentLibrary"}
#Iterate through all files from all document libraries
ForEach($List in $Lists)
{
$global:counter = 0
$Files = Get-PnPListItem -List $List -PageSize 2000 -Fields File_x0020_Size, FileRef -ScriptBlock { Param($items) $global:counter += $items.Count; Write-Progress -PercentComplete ($global:Counter / ($List.ItemCount) * 100) -Activity "Getting Files of '$($List.Title)'" -Status "Processing Files $global:Counter to $($List.ItemCount)";} | Where {$_.FileSystemObjectType -eq "File"}
$VersionHistoryData = @()
$Files | ForEach-Object {
Write-host "Getting Versioning Data of the File:"$_.FieldValues.FileRef
#Get File Size and version Size
$FileSizeinKB = [Math]::Round(($_.FieldValues.File_x0020_Size/1KB),2)
$File = Get-PnPProperty -ClientObject $_ -Property File
$Versions = Get-PnPProperty -ClientObject $File -Property Versions
$VersionSize = $Versions | Measure-Object -Property Size -Sum | Select-Object -expand Sum
$VersionSizeinKB = [Math]::Round(($VersionSize/1KB),2)
$TotalFileSizeKB = [Math]::Round(($FileSizeinKB + $VersionSizeinKB),2)
#Extract Version History data
$VersionHistoryData+=New-Object PSObject -Property ([Ordered]@{
"Library Name" = $List.Title
"File Name" = $_.FieldValues.FileLeafRef
"File URL" = $_.FieldValues.FileRef
"Versions" = $Versions.Count
"File Size (KB)" = $FileSizeinKB
"Version Size (KB)" = $VersionSizeinKB
"Total File Size (KB)" = $TotalFileSizeKB
})
}
$VersionHistoryData | Export-Csv -Path $CSVFile -NoTypeInformation -Append
}
How about generating the version history report for all sites in the site collection, including all libraries from subsites?
#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/Retail"
$CSVFile = "C:\Temp\VersionHistoryRpt.csv"
#Connect PnP Online
Connect-PnPOnline -Url $SiteURL -Interactive
#Delete the Output report file if exists
If (Test-Path $CSVFile) { Remove-Item $CSVFile }
Function Get-VersioningAnalysis([Microsoft.SharePoint.Client.Web]$Web)
{
#Connect to the Subsite
Connect-PnPOnline -Url $Web.Url -Interactive
#Get All Document Libraries from the Web - Exclude Hidden and certain lists
$ExcludedLists = @("Form Templates", "Preservation Hold Library","Site Assets", "Pages", "Site Pages", "Images",
"Site Collection Documents", "Site Collection Images","Style Library")
$Lists = Get-PnPList | Where-Object {$_.Hidden -eq $False -and $_.Title -notin $ExcludedLists -and $_.BaseType -eq "DocumentLibrary" -and $_.ItemCount -gt 0}
#Iterate through all files from all document libraries
ForEach($List in $Lists)
{
$global:counter = 0
$Files = Get-PnPListItem -List $List -PageSize 2000 -Fields File_x0020_Size, FileRef -ScriptBlock { Param($items) $global:counter += $items.Count; Write-Progress -PercentComplete ($global:Counter / ($List.ItemCount) * 100) -Activity "Getting Files of '$($List.Title)'" -Status "Processing Files $global:Counter to $($List.ItemCount)";} | Where {$_.FileSystemObjectType -eq "File"}
Write-Progress -Activity "Completed" -Completed
$VersionHistoryData = @()
$Files | ForEach-Object {
Write-host "Getting Versioning Data of the File:"$_.FieldValues.FileRef
#Get File Size and version Size
$FileSizeinKB = [Math]::Round(($_.FieldValues.File_x0020_Size/1KB),2)
$File = Get-PnPProperty -ClientObject $_ -Property File
$Versions = Get-PnPProperty -ClientObject $File -Property Versions
$VersionSize = $Versions | Measure-Object -Property Size -Sum | Select-Object -expand Sum
$VersionSizeinKB = [Math]::Round(($VersionSize/1KB),2)
$TotalFileSizeKB = [Math]::Round(($FileSizeinKB + $VersionSizeinKB),2)
#Extract Version History data
$VersionHistoryData+=New-Object PSObject -Property ([Ordered]@{
"Site Name" = $Web.Title
"Site URL" = $Web.URL
"Library Name" = $List.Title
"File Name" = $_.FieldValues.FileLeafRef
"File URL" = $_.FieldValues.FileRef
"Versions" = $Versions.Count
"File Size (KB)" = $FileSizeinKB
"Version Size (KB)" = $VersionSizeinKB
"Total File Size (KB)" = $TotalFileSizeKB
})
}
$VersionHistoryData | Export-Csv -Path $CSVFile -NoTypeInformation -Append
}
}
#Get all subsites in a SharePoint Online site
Get-PnPSubWeb -IncludeRootWeb | ForEach-Object {
#Call the function to get version size
Write-Host -f Cyan "Getting Version History Data for "$_.URL
Get-VersioningAnalysis $_
}
Generating a version history report for SharePoint Online using PowerShell can provide valuable insights into your site’s content. Following the script provided in this article, you can easily generate a version history report for a list or library in SharePoint Online and export it to a CSV file for analysis.
using pnp version history report for all sites in the site collection, including all libraries from subsites above script
#Get all subsites in a SharePoint Online site
Get-PnPSubWeb -IncludeRootWeb | ForEach-Object {
#Call the function to get version size
Write-Host -f Cyan “Getting Version History Data for “$_.URL
Get-VersioningAnalysis $_
}
Get-PnPSubWeb : The term ‘Get-PnPSubWeb’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:58 char:1
+ Get-PnPSubWeb -IncludeRootWeb | ForEach-Object {
+ ~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-PnPSubWeb:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Can you ensure you have the latest PnP.PowerShell module installed on your machine? How to Install the PnP PowerShell Module?
Please ensure you have the latest PnP PowerShell module installed in your machine, prior to running the script!
I am unable to run this script on a large library with more than Million items. Script runs fine if the library has less than a Million items with the below error.
… ListItems = Get-PnPListItem -List $ListName -Fields FileLeafRef -Page …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Unable to read data from the transport connection: An existing connection was forcibly closed by the remote
| host..
Hi PowerShell Guru! Thank you for putting this together. I want to retrieve the file version history in all subsites of a site collection. If you can provide an updated script to run through all the subsites in a given site collection would be greatly appreciated.
Sure! Post has been updated with the script to generate version history report for all sites in a site collection.
Hi, this is exactly what im looking for
However i’m unable to get this working on Sharepoint online.
I’m not sure if it because of the way we are trying to connect to sharepoint,
your script uses
#$Cred= Get-Credential
#$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
However to connect to sharepoint, i use
Connect-SPOService -Url https://companyname-admin.sharepoint.com
when i try updating to connect to
Connect-SPOService -Url https://companyname-admin.sharepoint.com
i get the following error
Error Generating version History Report! Exception calling “ExecuteQuery” with “0” argument(s): “The remote server returned an error: (401) Unauthorized.”
Help please.
Good day Salaudeen,
Hope you or anyone can assist. I am using the second script on the page and would like to add an additional column form the libraries. We have a column named DocumentVersion which is a choice column and would like it to be included in the report. I have tried ”DocumentVersion’ = $File.InternalName.DocumentVersion’ which does produce the additional column but all values is blank.
Any advice would really be appreciated.
Use $Item[“DocumentVersion”]
hello,
I am trying to find a PS script that will output to CSV Version number and number of versions for a site collection.
Please advise. Any help would be appreciated.
Thanks.
What if I wanted something more simple? For instance, I just want to hit a SPO or OD tenant, and get the amount of storage used, NOT counting additional versions? E.g., storage used only by current file versions.
I am using the last script and I was wondering what would need to be added so that the File_x0020_Type could be turned into a column? my edits dont load any data so i am not sure what i am doing wrong
nevermind, I was trying to call it correctly, i just needed to use $_.FieldValues.File_x0020_Type
Hello, thank you for sharing your script. I tried to run it three times, and it did scan, but after finishing over 1,000 files, it stopped. The error was: “Error Generating Version History Report! Exception calling “ExecuteQuery” with “0” argument(s): “File Not Found.” How can I keep the script running to finish all the files in the Documents library? I’m using the SharePoint Online PowerShell to get version history details of a document library. Thank you.
Need a way to only run the report on files with versions, instead of the entire library. What is the best approach to do this?
How can I list only files biiggest than 100 Mb for exemple?
thanks a lot!
How to add “Last modified” column to the rport? thanks!
How to modify from kb to mb?
Use this format:
$SizeinKB = 2040/1KB
$SizeinMB = $SizeinKB/1MB
Hello, is there a way to generate a report for ALL SharePoint Online sites in the tenant? We have many site collections and it’s tedious to report one by one. Thanks!
Hi, how can i expand the URL, field. Its returning a system collection value Microsoft.SharePoint.Client.FieldUrlValue
Use this script to get Hyperlink field values:
I am getting the below error, This is for online sharepoint
Error Generating Version History Report! Cannot find type [Microsoft.SharePoint.Client.SharePointOnlineCredentials]: verify that the assembly containing this type is loaded.
Is there any powershell code to get the latest version of file in document library ? Please can you help me with that.
Try: $File.Versions[$File.Versions.count-1]
HI, I want to compare the version details of two document library and need to get the details of the latest version of the file.Is that possible. Please help.
Hi, when i am trying to run the query on my SP library, it gives me the following error.
“Error Generating Version History Report! Exception calling “ExecuteQuery” with “0” argument(s): “The attempted operation is prohibited because it exceeds the list view threshold enforced by the administrator.”
can you please help me run the query and fix this error?
PS: i am using SharePoint Management Shell to run the query connecting my SharePoint Online doucment library.
/Azeem
One more thing. is this possible if we can get the report of a single folder within a document library? I mean instead of running the script on the whole document library, can we run the script on one single folder?
/Azeem
Script has been updated to handle larger libraries!
I need all versions of all items in a list.. can u help pls
Here you go: SharePoint Online: Export List Version History to Excel using PowerShell
Do you have a similar script for SP2013?
Yes! Here is the one for SharePoint On-Premises: https://www.sharepointdiary.com/2013/01/document-versions-size-report-powershell.html