Last year I wrote an article about using the PnP Provisioning engine to add references to documents in the Template file generated.
A couple of days a friend on linked in asked me if it were possible to include also all the documents versions in the Template file generated. So though about it and came up with a solution.
Basically the idea is of course to get all the versions of the document then download them and inject their reference in the Template pnp provisioning file.
First you have to know that when you get a reference to a file with
$folder = Get-PnPFolder -RelativeUrl $folderUrl
For ($i = 0; $i -lt $total; $i++) {
$file = $folder.Files[$i]
The $file.Versions will return an error as the collection has not being initialised. This is because the collection property has not been specified. So in order to load the .Version collection you have to specifically load it with
$total = $folder.Files.Count
$ctx = Get-PnPContext
For ($i = 0; $i -lt $total; $i++) {
$file = $folder.Files[$i]
$ctx.load($file.Versions)
$ctx.ExecuteQuery()
Now we can iterate through the Version collection and get the Url property to download the file.
Again I am not sure why if I used the Get-PnpFile -Url $file.Url it was returning me an error 404 not found so I used the WebClient object to download the file with
$webClient = New-Object System.Net.WebClient
$webClient.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userName, $sPassword)
$webClient.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
$webclient.DownloadFile($ServerFileLocation,$DownloadPath)
If we put it all together my ProcessFolder function becomes
function ProcessFolder($folderUrl, $destinationFolder) {
Write-Output "Folder URL " $folderUrl " destinationFolder " $destinationFolder
$folder = Get-PnPFolder -RelativeUrl $folderUrl
$tempfiles = Get-PnPProperty -ClientObject $folder -Property Files
if (!(Test-Path -path $destinationfolder )) {
$dest = New-Item $destinationfolder -type directory
}
$total = $folder.Files.Count
$ctx = Get-PnPContext
For ($i = 0; $i -lt $total; $i++) {
$file = $folder.Files[$i]
$ctx.load($file.Versions)
$ctx.ExecuteQuery()
foreach($version in $file.Versions)
{
$filesplit = $file.Name.split(".")
$fullname = $filesplit[0]
$fileext = $filesplit[1]
$FullFileName = $fullname+"\"+$version.VersionLabel+"\"+$file.Name
$fileURL = $destination+"/"+$version.Url
$DownloadPath = $FullFileName
if (!(Test-Path ($destinationfolder + "\" + $fullname + "\" + $version.VersionLabel)))
{
New-Item ($destinationfolder + "\" + $fullname + "\" + $version.VersionLabel) -type directory -Force
}
HTTPDownloadFile "$fileURL" ($destinationfolder + "\" + $fullname + "\" + $version.VersionLabel + "\" + $file.Name)
$versionSourceFolder = "./" + $siteTitle + "/" + $folder.Name + "/" + $fullname + "/" + $version.VersionLabel + "/" + $file.Name
Add-PnPFileToProvisioningTemplate -Path ($saveDir + "Template.xml") -Source $versionSourceFolder -Folder $folderUrl -FileLevel Published
}
Get-PnPFile -ServerRelativeUrl $file.ServerRelativeUrl -Path $destinationfolder -FileName $file.Name -AsFile -Force
Add-PnPFileToProvisioningTemplate -Path ($saveDir + "Template.xml") -Source ($destinationfolder + "\" + $file.Name) -Folder $folderUrl -FileLevel Published
}
}
with the HTTPDownloadFile function
function HTTPDownloadFile($ServerFileLocation, $DownloadPath)
{
$userName = "LOGIN_NAME"
$password = "PASSWORD"
#create secure password
$sPassword = $password | ConvertTo-SecureString -AsPlainText -Force
$webClient = New-Object System.Net.WebClient
$webClient.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userName, $sPassword)
$webClient.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
$webclient.DownloadFile($ServerFileLocation,$DownloadPath)
}
The complete script is available on github at https://github.com/alaabitar/provisioning/blob/master/scriptUpgraded.ps1