During my last project we were asked to create a fairly simple site template on Office 365. I typically cringe when I hear the word site definition / site template or web template. The reason goes way back to the beginning of my career with SharePoint. One of my first projects I had to upgrade a site definition from 2007 to 2010. I’m not going to complain too much but let’s just say that there was barely any documentation on how to accomplish this. For a n00b I struggled through it and I guess I completely it successfully.

Fast forward to today… the last time I created a web template for Office 365 I was able to build the site and then “Save as Template”. This worked because it was not a publishing site, but a team site. That template saved successfully by it created some monstrous WSP with tons of files, folders, feature and XML definitions. To make any changes to the template I had to scan through those XML definitions. The experience was not fun to say the least.

I was researching the deep and dark interwebs on “the best method to create site templates on Office 365”. The result of that research showed that the shift is towards remote site provisioning using either your client machine, a provider hosted add-in or another method like web job, remote timer job, Azure function. Basically anything capable of running remote client object model code to programmatically build out your site.

I chose to perform remote site creation via PnP-Powershell [See GitHub Site]. The PnP-Powershell team has been doing fantastic work. They currently a couple of ways to do remote site provisioning.

  1. provision from a live site (as a template)
  2. provision from a xml definition – this can be exported from a live site and saved for reuse

Unfortunately I wasn’t able to get either of those options to work for me because of a know issue that they are working on. [Apply-PnPProvisioningTemplate : Value cannot be null. Parameter name: stream #1010]. I decided that I was going to continue to use the PnP-Powershell commands to programmatically create the site instead of using some of their provisioning commandlets.

If your just getting started then I suggest checking out these following resources on remote provisioning

Getting Started

The first thing you’ll need to do is visit the GitHub site for PnP-PowerShell – https://github.com/SharePoint/PnP-PowerShell. You’ll need to make sure that you have the pre-requisites installed. You also need to install the PnP commandlets with the command below

In the following paragraphs I’m going to demonstrate the code that was ultimately used as the solution.

My code template required the following items:

  1. Lists
    1. Announcements
    2. Calendar
  2. Web Parts on Home Page
    1. Announcements
      1. Custom Display (using display template)
    2. Calendar
    3. Document Library

This should give you a basic idea of what we need to accomplish.

The Commands

Next up is the current set of commands that I ran to provision the new site.

This worked for what we needed however I wanted to point out a few things

1. There is a problem is you run this in a script. If you run this as part of a .ps1 it seems to throw an error but doesn’t appear to cause an issue. I write the out as $null an continue. If you type it into the command line it doesn’t throw an error. [Related:Add-SPOView breaks View Menu #320]

2. Chrome Type Property – It’s not clearly listed anywhere and it took some playing around till I got this to work. I’m assuming since it accepted 2 that it’s the PartChromeType Enumeration (i added the red numbers in the picture below)

Summary

In end the I was happy with the results. I found out shortly after speaking with a colleague, Josh Carlisle aka our provisioning guru, that this could be all nicely packaged up and put into an Azure function. This way that someone doesn’t have to run the code on their desktop. It could be implemented in a cloud way where you just need to trigger that function to run… possibly using Flow where you just enter the site creation information into a list and it fires away or a custom form. Bottom line is that I’m excited to really see the potential of the PnP initiatives. It has some glitches with some of the commandlets during the time that I tried it but I can see how it will become very powerful once it fully matures.

Comments
  • Poovi
    Posted at 7:15 am October 5, 2017
    Poovi
    Reply
    Author

    hi,
    Is there any possibilities to take a list or site as template and create a new list using that template using PnP powershell code.
    I could not find any commands for that.
    Please help me with sample code.

    Thanks,
    Poovi

    • Tom Daly
      Posted at 7:47 pm October 5, 2017
      Tom Daly
      Reply
      Author

      Yes that is possible. I have a posting coming out soon on that but in the meantime you can check out these commands below. (you can export a template from a site then re-import

      This is slightly dated (the commands have been renamed) but the idea is the same – [https://www.youtube.com/watch?v=4-CwS6AD4G4]

      Provisioning Section
      [https://github.com/SharePoint/PnP-PowerShell/blob/master/Documentation/readme.md#provisioning]

      Get-PnPProvisioningTemplate
      [https://github.com/SharePoint/PnP-PowerShell/blob/master/Documentation/GetPnPProvisioningTemplate.md]

      Apply-PnPProvisioningTemplate
      [https://github.com/SharePoint/PnP-PowerShell/blob/master/Documentation/ApplyPnPProvisioningTemplate.md]

      There are a few options involved. You can create a site as a template and export templates to disk, azure, and i forget the last one. Then you can apply that to a new site. You can do this with the powershell commands or the C# version.

      You can also take a peek at an example project I have where I create 3 lists based on the PnP Powershell. Announcements / Events / Custom [QuickLinks]. The templates might not run in that configuration b/c there are PnP:Files that don’t exist but feel free to download and play with it.
      [http://thomasdaly.net/wp-content/uploads/2017/10/provisioning.zip]

  • Leave a Reply to Tom Daly
    Cancel Reply