SharePoint Online PowerShell : PnP Provisioning Process (Part 2)

Introduction

This article is in continuation of my previous article, in the first part ,I covered downloading of all artifacts and template from SharePoint Online. In this part, lets focus on setting up a new site collection and applying of provisioning template.

Pre-requisite is to Install latest SharePointPnPPowerShellOnline.msi from locationhttps://github.com/SharePoint/PnP-PowerShell/releases  .

Structure

We will need to divide overall process in 5 steps, In this article I will cover the last 3 steps.

  • Download artifacts from existing site.
  • Download PnP Provisioning template from existing site.
  • Modify PnP Template to include downloaded artifacts and change old site references.
  • Create Site Structure.
  • Apply PnP Provisioning template to destination site.

For reference, I will use “C:\Scripts” as local folder.

Modify PnP Template 

Upon continuation from the previous article, after running Get-PnPProvisioningTemplate command, we have basic template with all setting and Home.aspx page. We will need to perform the following changes so that it contains all downloaded artifacts:

  • Change all reference in Provisioning template to new site collection relative path
  • Add downloaded files references in Provision template.

Change references 

This can be done with simple PowerShell function; this function will modify template xml and find-replace the references to new site collection.e.g. initial site collection is “/Site1” and new site collection is “/Site2” 

$path : Path of the Provisioning template e.g. c:\Scripts\site1\site1Template.xml
$oldString: “Site1”
$newString: ”Site2”

   function   ModifyAllTemplateForRelativeURL($path, $oldString,$newString){
     $xmlLocation     =     $path  ;
   (  Get-Content     -Path     $xmlLocation     -ErrorAction     Ignore  )   |     ForEach-Object   {     
        $_     -Replace     $OldString  ,     $NewString  ;
    }   |     Set-Content     -Path     $xmlLocation
  } 

We will need to run this command on all downloaded provisioning template.

Include downloaded artifacts 

We will use PnP command “Add-PnPFileToProvisioningTempalte” to add downloaded files in Provisioning template

  $Folders = @('Documents','Banner')
   $xmlLocation = "c:\Scripts\site1\site1Template.xml'
   $FoldersLocation = "C:\Scirpts\Staging\site1"

    $Folders | ForEach-Object {
   $path = $FoldersLocation + "\" + $_;
   (dir $path -Recurse) | %{
  try{
    $FName = "{site}" + $_.Directory.FullName.Substring($FoldersLocation.Length)
    Add-PnPFileToProvisioningTemplate -Path $xmlLocation -Source $_.FullName -Folder $FName -Container $_.Directory.FullName  -ErrorAction Ignore
  }
 catch{}
 }
}

more on “Add-PnPFileToProvisioningTempalte https://msdn.microsoft.com/en-us/pnp_powershell/addpnpfiletoprovisioningtemplate 

After running above command, PnP Provisioning template will get modified similar to as shown below. This command will add all downloaded file references 

<pnp:File Src="/Staging/Style Library/plugins/froala-editor-2.3.5/js/languages/zh_tw.js" Folder="{site}/Style Library/plugins/froala-editor-2.3.5/js/languages" Overwrite="true" />

<pnp:File Src="/Staging/Style Library/plugins/froala-editor-2.3.5/js/plugins/align.min.js" Folder="{site}/Style Library/plugins/froala-editor-2.3.5/js/plugins" Overwrite="true" />

<pnp:File Src="/Staging/Style Library/plugins/froala-editor-2.3.5/js/plugins/char_counter.min.js" Folder="{site}/Style Library/plugins/froala-editor-2.3.5/js/plugins" Overwrite="true" />

<pnp:File Src="/Staging/Style Library/plugins/froala-editor-2.3.5/js/plugins/code_beautifier.min.js" Folder="{site}/Style Library/plugins/froala-editor-2.3.5/js/plugins" Overwrite="true" />

<pnp:File Src="/Staging/Style Library/plugins/froala-editor-2.3.5/js/plugins/code_view.min.js" Folder="{site}/Style Library/plugins/froala-editor-2.3.5/js/plugins" Overwrite="true" />

<pnp:File Src="/Staging/Style Library/plugins/froala-editor-2.3.5/js/plugins/colors.min.js" Folder="{site}/Style Library/plugins/froala-editor-2.3.5/js/plugins" Overwrite="true" />

We need to careful while running this command so that it properly format the source and destination location:

Src: It will be the relative path of the file from the place we are running the script. As our scripts are at location "C:\Scripts" and file location is 

C:/scripts/Staging/Staging/Style Library/plugins/froala-editor-2.3.5/js/plugins/colors.min.js

Folder: Location in the site collection where we want to move
{site}/Style Library/plugins/froala-editor-2.3.5/js/plugins
Note: there is "/" in path string not "\

After this step we have all our files included in the Provisioning template.
We will need to run similar command for each template where we need to include downloaded file references.

Create Site Collection

Create needed site hierarchy as similar to the parent site collection, using " New-PnPWeb" command.

 New-PnPWeb -Title 'Site1' -Url 'site1'  -Template 'CMSPUBLISHING#0'  -BreakInheritance -Verbose  -Debug  | Out-Null 
New-PnPWeb -Title 'site2' -Url 'site2' -Template 'CMSPUBLISHING#0' -BreakInheritance -Verbose -Debug  | Out-Null 

These are all sub sites under root site collection. If we have sub site under sub site, then we will create it while applying provisioning template.

Apply PnP Provisioning Template

Now we are at the last step of migration and ready to apply the provisioning template to new site collection. 
We will iterate through each site collection / sub sites and apply the template

       $credentials   = Get-Credential 
     Connect-PnPOnline     -Url     $targetUrl     -Credentials     $credentials     -CreateDrive     cd “C:\Scripts\Staging\site1”
     Apply-PnPProvisioningTemplate     -Path     site1Template.xml     -Verbose     -Debug     -ErrorAction     Ignore

         cd "   subsite  "
     New-PnPWeb     -Title     'SubSite'     -Url     'subsite'     -Template     'CMSPUBLISHING#0'     -BreakInheritance     -Verbose     -Debug     -ErrorAction     Ignore     |     Out-Null
     $subsuteUrl   = $targetUrl.TrimEnd('\') + "/subsite";
     Connect-PnPOnline     -Url     $subsuteUrl   -Credentials     $credentials      -CreateDrive
     Apply-PnPProvisioningTemplate     -Path     subsiteTemplate.xml     -ExcludeHandlers     TermGroups  ,  Navigation     -Verbose     -Debug     -ErrorAction     Ignore

While applying provisioning template we are going through following process:

  • Connect to the new site collection "Site1".
  • Go to the location in folder where we have modified Provisioning template for "Site1".
  • Apply provisioning template to the site collection.
  • If we have sub sites under "Site1", then go create the new subsite under site collection "Site1".
  • Go to the location of subsite template, and apply the template.

These steps will repeat for all the sub sites.

 Above example has used "Publishing" template to create new site/sub sites but in real scenario it should match with the template as in source site or sub site. 

More on Apply PnP provisioning can be found here : https://msdn.microsoft.com/en-us/pnp_powershell/applypnpprovisioningtemplate and we should use Exclude handler for all the part which we don’t want to migrate.

Note: We could face few issues while applying provisioning, which can be related to "user account not found" / "Managed metadata field" / "Calculated field"  etc. This needs to be handle case-by-case.  
This article will provide a basic structure on how to plan and migrate a site in SharePoint Online using PnP PowerShell commands. 

Back to Top