SharePoint Online: Version History Report using PowerShell

Requirement: Generate version history report for all sites in a SharePoint site collection.
version history report for sharepoint online using powershell

SharePoint Online PowerShell to Get Version History Details of a Document Library
Version history feature in SharePoint Online maintains a history of all changes that have been 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.
#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://crescentintranet.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 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://crescentintranet.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
#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 -UseWebLogin

$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:
pnp powershell to generate version history report in sharepoint online

Similarly, to generate the version history analysis for all libraries in 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 -UseWebLogin

#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
}

10 comments:

  1. Do you have a similar script for SP2013?

    ReplyDelete
  2. I need all versions of all items in a list.. can u help pls

    ReplyDelete
  3. 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

    ReplyDelete
    Replies
    1. 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

      Delete
    2. Script has been updated to handle larger libraries!

      Delete
  4. 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.

    ReplyDelete
  5. Is there any powershell code to get the latest version of file in document library ? Please can you help me with that.

    ReplyDelete

Please Login and comment to get your questions answered!

Powered by Blogger.