Getting Started with PnP PowerShell in Office 365 and SharePoint

Pieter Veenstra

by Pieter Veenstra on 8/19/2016

Share this:

Article Details

Date Revised:

Applies to:
Office 365 PnP, PowerShell, SharePoint

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

What is PnP PoSh?

To answer this question, I will probably first have to answer, 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’ll first discuss how sites have been provisioned throughout the years.

Site provisioning

Historically, SharePoint developers created farm solutions 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 sites.

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 than they were worth. Quite often, this 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 recently changed my mind on this.) And solution files aren’t great either. So what is the alternative?

Manually make your 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 a PowerShell module is loaded when you restarted your PowerShell.

Ok, all great stuff! Time to get started.

So I was talking about exporting and importing a site. We’ve got three commands to help us with this.

  • Connect-SPOnline
  • Get-SPOProvisioningTemplate
  • 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 it 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 content type 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 filename.

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

This will create an 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 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 supported.

By default, a progress bar will be shown

It often is useful to get some additional information. See my post, How to Debug the OfficeDev PnP Provisioning Engine

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:

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

If you want to apply it to a sub site, do this:

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, because 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 would now only need to run a PowerShell cmdlet 1000 times instead of updating 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:

You can find Pieter’s original post here:

Topic: Development - Recent

Sign in with

Or register