Share via


Versioning and SharePoint: the Powershell perspective (part 1)


Overview

Versioning in lists and libraries enables us to track and manage information as it evolves and to view and restore earlier versions if necessary. That is very useful, e.g. when people realize that earlier versions of an item might be more accurate than later ones. Some organizations retain multiple versions of items in their lists for legal reasons or audit purposes.1 

Application

Versioning has multiple uses. With the setting enabled, we can:

Track history of a version When versioning is enabled, we can see when an item or file was changed and who changed it. We can also see when properties (information about the file) were changed. For example, if someone changes the due date of a list item, that information appears in the version history. We can also see the comments people make when they check files into libraries.

Restore a previous version If we made a mistake in a current version, if the current version is corrupt, or if we simply like a previous version better, we can replace the current version with a previous one. The restored version becomes the new current version.

View a previous version We can view a previous version without overwriting our current version. If we are viewing version history within a Microsoft Office document, such as a Word or Excel file, we can compare the two versions to determine what the differences are.
From: How does versioning work in a list or library?

Supported lists and libraries

Versioning is available for list items in all default list types—including calendars, issue tracking lists, and custom lists. It is also available for all file types that can be stored in libraries, including Web Part pages. By default, versioning is turned off (apart from new OneDrive for Business libraries)

Required permissions

Anyone with permissions to manage lists can turn version on or off for a library.2 When we look at the default permission levels in the tenant we can see that Full Control, Design or Edit include the permissions to manage lists.3  We  can view it either in the table here or on our own tenant under :

https://TENANT.sharepoint.com/sites/SITECOLLECTIONNAME/\_layouts/15/start.aspx#/\_layouts/15/editrole.aspx?role=ROLENAME , for example:

https://trialtrial125.sharepoint.com/sites/TeamsiteWithLibraries/\_layouts/15/start.aspx#/\_layouts/15/editrole.aspx?role=Design

We can also create a custom permission level that will include "Manage Lists" permissions for users to be able to change the versioning settings.

When versions are created

There are several actions that trigger version creation. When versioning is enabled, versions are created in the following situations:

* When a list item or file is first created or when a file is uploaded. Note that if you have enabled a library setting that requires file checkout, you have to check the file in to create its first version.

* When a file is uploaded that has the same name as an existing file and the Add as a new version to existing files check box is selected.

* When the properties of a list item or file are changed.

* When a file is opened, edited, and saved. A version is created when we first click Save. It retains the new version number for the duration of the current editing session, even though we might save it several times. When we close it and then reopen it for another editing session, another version is created.

* During co-authoring of a document, when a different user begins working on the document or when a user clicks save to upload changes to the library. The default time period for creating new versions during co-authoring is 30 minutes. This is configurable per web application in SharePoint on-premises. This setting is not configurable in SharePoint Online.

Turn on versioning from the User Interface

1. Open the list or library.

2. Click on the List/Library Tab.

3. On the right-hand side click on Library Settings.

  1. Under General Settings choose Versioning Settings.

  1. Under Document Version History choose option Create major versions.

Enable versioning for a list using PowerShell

Prerequisites

SharePoint Online SDK. 

For detailed instruction with screenshots on how to install SharePoint Online SDK and run Powershell ISE please refer here.

Step-by-step comments

In the ISE Window, add the paths to SharePoint Online SDK installed earlier. Verify if the paths are exactly the same, e.g. on Windows Server, we may need to change 15 into 16:

Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

Enter the credentials, the site, and list where we want to change the versioning setting

$AdminPassword=Read-Host -Prompt "Enter password"  -AsSecureString
$username="trial@trialtrial125.onmicrosoft.com"
$Url="https://trialtrial125.sharepoint.com/sites/teamsitewithlibraries"
$ListTitle="Not-Empty-Document-Library"
$Versioning=$true

It is a good practice to keep all information that a user may change in one place, instead of spread across the whole code for us to search whenever we want to re-use it. So let's decide now whether we will want to enable versioning or disable it and store this decision as a bool variable:


      $Versioning    =    $true  

As we see, I have decided to enable the versioning in my list.
 
Now let's do something with the data we provided. For most of the actions, it is useful to put them in the form of a function. Functions are blocks of code designated to perform a particular task. If we encapsulate our cmdlets in such a block, it will be very easy to re-use it later on and that's what automation is all about:


      function Set-SPOListVersioning
      {  
   
      }  

The function can take parameters, defined either in ( ) next to the function name or in a way shown below:

  


      param (  
                        [Parameter(Mandatory=      $true      ,Position=0)]      
                        [string]      $ListName      ,      
                        [Parameter(Mandatory=      $true      ,Position=1)]      
                        [bool]      $Versioning      ,      
                        [Parameter(Mandatory=      $true      ,Position=2)]      
                        [string]      $Username      ,      
                        [Parameter(Mandatory=      $true      ,Position=3)]      
                        [string]      $Url      ,      
                        [Parameter(Mandatory=      $true      ,Position=4)]      
                        $password      
                        )      
Let's create the context now for our actions. We will be operating within the site/ site collection we defined earlier in the $Url variable 


      
  

      $ctx    =New-Object Microsoft.SharePoint.Client.ClientContext(    $Url    )  

Add the credentials to the context, so that we can authenticate.

 


      $ctx    .Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials(    $Username    ,     $password    )  

.ExecuteQuery() isn't necessary at this stage, but I like to run it early to make sure that authentication ran smoothly. If there is an error in the $Url, $Username, $password, or the site doesn't exist, it will throw us an error and we can narrow down our troubleshooting scope.

 

  
      $ctx    .ExecuteQuery()  

Retrieve the list in question using its .Title property

      $ll    =    $ctx    .Web.Lists.GetByTitle(    $ListTitle    )    $ctx  .Load(  $ll  )

Update its EnableVersioning property to what we defined earlier in the $Versioning variable

      $ll    .EnableVersioning =     $Versioning               
     
$ll.Update()

In order to process this request we need .ExceuteQuery()

      $ctx    .ExecuteQuery()  

Try and catch in case it fails

                 try  
                         {      
                        $ctx      .ExecuteQuery()      
                        Write-Host       "Done" -ForegroundColor Green  
                       }      
   
                       catch [Net.WebException]       
                        {      
                         
                         
                        }      

In case it fails, it is always useful to retrieve the exact error message. For my purposes, it is enough to write it in the console window using Write-Host cmdlet, but we can even export it a separate report using Export-CSV -Append cmdlet

                  try  
                          {      
                        $ctx      .ExecuteQuery()      
                        Write-Host       "Done" -ForegroundColor Green  
                        }      
   
                       catch [Net.WebException]       
                        {      
                         
                            Write-Host       "Failed" $_.Exception.ToString() -ForegroundColor Red  
                        }      

At the end let us run the cmdlet we have created using as input the data we inserted in the beginning

      Set-SPOListVersioning -ListName     $ListTitle -Versioning $Versioning -Username $username -Url $Url -password $AdminPassword

As an alternative we can export the cmdlet, save the file as .psm1 extension and instead of Powershell script we would receive a Powershell module. After importing this module to our Powershell the cmdlet would be available with the standard set of cmdlets 

      Export-ModuleMember     "Set-SPOListVersioning"  

Full code

#
# Created by Arleta Wanat, 2015
#
 
function Set-SPOListVersioning
{
param (
        [Parameter(Mandatory=$true,Position=0)]
        [string]$ListName,
        [Parameter(Mandatory=$true,Position=1)]
        [bool]$Versioning,
        [Parameter(Mandatory=$true,Position=2)]
        [string]$Username,
        [Parameter(Mandatory=$true,Position=3)]
        [string]$Url,
        [Parameter(Mandatory=$true,Position=4)]
        $password
        )
 
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
  $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $password)
  $ctx.Load($ctx.Web)
  $ctx.ExecuteQuery()
  $ll=$ctx.Web.Lists.GetByTitle($ListTitle)
  $ctx.Load($ll)
 
$ll.EnableVersioning = $Versioning 
    $ll.Update()
 
    try
    {
        $ctx.ExecuteQuery()
        Write-Host "Done" -ForegroundColor Green
       }
 
       catch [Net.WebException]
        {
             
            Write-Host "Failed" $_.Exception.ToString() -ForegroundColor Red
        }
         
 
} 
 
 
# Paths to SDK. Please verify location on your computer.
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
 
# Insert the credentials and the name of the site and list
$AdminPassword=Read-Host -Prompt "Enter password" -AsSecureString
$username="trial@trialtrial125.onmicrosoft.com"
$Url="https://trialtrial125.sharepoint.com/sites/teamsitewithlibraries"
$ListTitle="Not-Empty-Document-Library"
$Versioning=$true
 
   
Set-SPOListVersioning -ListName $ListTitle -Versioning $Versioning -Username $username -Url $Url -password $AdminPassword

You can also download it here.

Minor versioning

In lists, all versions are tracked in the same way.4 In libraries, however, SharePoint Online can differentiate between minor and major versions. If your business requires, you might want to track both major and minor versions of a file. Minor versions are often called drafts. A major version, such as that in which a new chapter is added, can signal that a document is ready for review by a wide audience, whereas the minor (draft),  e.g. where a spelling error is corrected, may mean that the version is a work-in-progress and not yet ready for wide circulation. 

When versions are created

 
Tracking both kinds of versions also helps make the version history more meaningful. When major and minor versions are being tracked, a version is stored by default as a minor version, unless the you designate the version as major. When someone saves a file and closes it, the version is tracked as a minor version; the file must be published to become a major version. If an author checks out a file and checks it back in, the author is prompted to choose whether to check in a major version or a minor version.

The multiple possibilities mean that there can be up to three current versions of a file at any given time: the checked-out version, the latest minor or draft version, and the latest published or major version. All other versions are considered historical versions. Some current versions are only visible to users who have permissions to view them.5

Numbering

Version numbers are automatically added each time a new version is created. In a list or library that has major versioning enabled, the versions have whole numbers, such as 1.0, 2.0, 3.0, and so on. In libraries, where minor versions are being tracked, they have decimal numbers such as 1.1, 1.2, 1.3, and so on. When one of those versions is published as a major version, its number becomes 2.0. Subsequent minor versions are numbered 2.1, 2.2, 2.3, and so on. You can read more on versioning numbering here.

Minor versioning from User Interface

When you configure versioning at the time when you create a list or library, simple versioning is enabled by default, and you don't have the option of enabling major and minor versioning. To enable major and minor versioning you have to enter the settings of an already created library and follow these steps:

  1. Open the list or library

2. Click on the List/Library Tab

  1. Under General, Settings choose Versioning Settings

  2. Under Document Version History choose option Create major and minor (draft) versions

  1. Click Save.

Powershell

Minor versioning requires an only minor change in the above-mentioned code, so I will refrain from commenting every bit. The property responsible for minor versions is also a bool called.EnableMinorVersions. Setting it to $true will enable minor and major versions, setting it to $false will disable versioning. 

$ll.EnableMinorVersions = $Versioning

Full Code

function Set-SPOListVersioning
{
param (
        [Parameter(Mandatory=$true,Position=0)]
        [string]$ListName,
        [Parameter(Mandatory=$true,Position=1)]
        [bool]$Versioning,
        [Parameter(Mandatory=$true,Position=2)]
        [string]$Username,
        [Parameter(Mandatory=$true,Position=3)]
        [string]$Url,
        [Parameter(Mandatory=$true,Position=4)]
        $password
        )
 
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
  $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $password)
  $ctx.Load($ctx.Web)
  $ctx.ExecuteQuery()
  $ll=$ctx.Web.Lists.GetByTitle($ListTitle)
  $ctx.Load($ll)
 
$ll.EnableMinorVersions = $Versioning 
    $ll.Update()
 
    try
    {
        $ctx.ExecuteQuery()
        Write-Host "Done" -ForegroundColor Green
       }
 
       catch [Net.WebException] 
        {
             
            Write-Host "Failed" $_.Exception.ToString() -ForegroundColor Red
        }
         
}
 
 
# Paths to SDK. Please verify location on your computer.
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
 
# Insert the credentials and  the name of the site and list
$AdminPassword=Read-Host -Prompt "Enter password"  -AsSecureString
$username="trial@trialtrial125.onmicrosoft.com"
$Url="https://trialtrial125.sharepoint.com/sites/teamsitewithlibraries"
$ListTitle="Not-Empty-Document-Library"
$Versioning=$true
 
  
Set-SPOListVersioning -ListName $ListTitle -Versioning $Versioning -Username $username -Url $Url -password $AdminPassword

You can also download the script here.

Part 2 Enable/disable versioning for all lists and libraries in one site
Part 3 Tweaks and Variations
Part 4 Retrieve all file versions using PowerShell

      Enable versioning programmatically using Powershell and CSOM    
  
Enable minor versions programmatically using Powershell and CSOM

  Other languages

This site is available in other languages:


SharePoint Online: Delete unique permissions in multiple lists using CSOM (en-US)

SharePoint Online: Disable or enable attachments to list items using Powershell (en-US)

    http://c.statcounter.com/10342264/0/d7616740/0/