In recent weeks I’ve given quite a few of my colleagues in introduction into PnP PowerShell.

PnP PowerShell is part of the Office 365 Developer Patterns & Practices initiative.  In this post I’m going to look at some of the the PnP Posh cmdlets to export and import sites. 687474703a2f2f692e696d6775722e636f6d2f6c3031686876452e706e67

What is PnP Posh?

To answer this question I will probably first have to answer the what is PnP?

Although PnP is a lot more than just the provisioning engine I’m going to start with the provisioning engine story.

Before I answer these questions I’m first having a look at how sites have been provisioned through out the years.

Site Provisioning

Historically SharePoint developers created farm solution or sandbox solutions  (.wsp files) to deploy/provision their sites. Using features you can create lists, content types and all sorts of other building blocks that SharePoint people like to see in their site.

These solutions need to first be installed (restarting IIS and creating unwanted downtime). Additionally updating features can be quite a difficult task. Initiatives like Feature Upgrades never really worked. Or at least they were more hassle then they were worth. Quite often this then resulted in additional solution files with features called “Fix my content types”.

Also migrating from SharePoint 2007 to SharePoint 2010 to SharePoint 2013 meant that solutions needed to be repackaged (Did anybody keep a copy of the code? Which consultancy developed which solution?).

So in short I don’t like features. (I changed my mind on this in recent times 🙂 ). And solution files aren’t great either.

So what is the alternative.

  • Manually make you changes.

But I want something that is deployable. This is exactly where the PnP comes in.

PnP Provisioning Engine

The PnP PoSh converts sites into Xml and lets you apply this Xml to other sites.

How do I get this PnP Posh? Every month a new version of binaries are release in this Github project. Look in the Binaries folder for the right version of the .msi packages. In my case I’m downloading the SharePoint Online version.


Then run the msi ( don’t forget to unblock the file).


Simply accept the terms and click on the install button and your PnP PowerShell is up and running.

Now start your PowerShell. I’m using Windows PowerShell ISE as it helps with debugging your scripts. You will now find that your PowerShell Module is loaded when you restarted you r PowerShell.Modules

Ok, all great stuff ! Time to get started.


So I was talking about exporting and importing a site.

We’ve got 3 commands to help us with this.

  1. Connect-SPOnline
  2. Get-SPOProvisioningTemplate
  3. Apply-SPOProvisioningTemplate


Connect-SPOnline connects you not only to your Office 365 site but also your On-premises site.

It uses the following syntax:


If you wanted to you can also connect to a subsite but I’ve found that that just makes things complicated. I just connect to the root web in my site collections.


Once connected Get-SPOProvisioingTemplate lets you collect a site, list, field or contenttype as xml.

The simple syntax:


Could it be any easier? Well the above command will turn my site into Xml. However it will generate the Xml as output to your screen. So we might want to specify a file name

Get-SPOProvisioningTemplate -Out C:\temp\test.xml

This will now create in xml file.  In the latest version of the PnP PoSh .pnp files can be created as well. Where .xml files give you plain xml the .pnp files give a an OpenXml based package. Ah, we’re going back to a single solution file but this time without features.

Get-SPOProvisioningTemplate -Out C:\temp\test.pnp

Both of the file formats are support.

By default a progress bar will be shown


It often is useful to get some additional information. See my post

Ok, so now we have an xml containing my site how do I now apply this to another site?


To apply a template use the Apply-SPOProvisioingTemplate Cmdlet.

The syntax is simple again:

Apply-SPOProvisioningTemplate -Path c:\temp\test.xml

If you want to apply it to a sub site:

Apply-SPOProvisioningTemplate -Path c:\temp\test.xml -Web /mysubsite

If you want to apply  just the part of your xml. e.g just the lists or just the workflows. Then you can use the -Handlers switch

Apply-SPOProvisioningTemplate -Path c:\temp\test.xml -Web /mysubsite -Handlers Lists

Similar to the Handlers switch you can also use ExcludeHandlers to exclude parts of your template.

This switch is especially useful when you debug the templates, but also if your template depends on something being created first.  Imagine when you deploy the template to a sub site and you want your columns to be created at the site collection level. Do you really want to reapply the whole site collection’s root web template? Maybe or maybe not. At least you now have options.

You can of course reapply the template as often as you want. As the PowerShell Cmdlets will check which parts of your template already exist. Imagine if you wanted to add a list to 1000 project sites. You lwould now only need to run 1000 time a PowerShell cmdlet instead of updating a 1000 sites.


With a few easy PowerShell commands it is now very easy to copy structures of a site to another site using the PnP PowerShell commands. Without the need for a developer.

If you want more:

Overview PnP PowerShell Commands

Webcast with Vesa Juvonen and Erwin van Hunen