Have you ever tried to migrate a site from an on-premises SharePoint environment to Office 365? Or have you tried keeping development, test and production sites in sync?

Office 365 - SharePoint - PnP Tenant Migration Sample is now available! Microsoft Office 365 failed businessman 2

Within an on-premises environment you would have been likely to hit issues with custom solutions? Or you might have hit issues with recreating sites exactly the same way as they were before? Keeping internal field names and GUIDs the same can be a tricky job. Additionally search configurations can be difficult to replicate.

When using farm solutions to provision/update your sites it can be difficult update a site, especially when users can create fields, content types and lists manually.

When all is created and recreated manually within SharePoint then it’s just impossible to keep sites exactly the same.

Since early 2016 I’ve been playing with PnP-PowerShell. With some simple cmdlets it is possible to export and import sites. It is however easier said than done and I’ve seen many people new to PnP complain that it isn’t mature enough while they hit some minor issues that could easily be worked around. Additionally, it is hard to keep up with the development happening. So many cmdlets and options to cmdlets have been added.

Recently, I’ve already described a solution that improves PnP-PowerShell to migrate whole site collections with a single click. I’ve developed the ideas of this solution during some of my projects. If you are less interested in doing these kind of site migrations yourself then I’m happy to get you in touch with the right people at Triad. Just leave a comment below.

By creating a config.xml it is possible to control a set of scripts that will export, import or copy multiple sites.

The solution is now available on github within the PnP-PowerShell master branch .

Big advantages of this solution:

  • It can handle multiple pages, unlike PnP out of the box
  • It can handle complex combinations of look-up fields and lookup lists
  • One click for
    • Reading all templates form a whole tenant
    • Updating a whole tenant with the set of templates
    • both reading templates and applying them
  • An option to disable/enable features
  • Fixing template issues in between getting the templates and applying them without any user intervention such as:
    • Updating security setting (usernames in different domains)
    • Fixing templates with mixes of team sites and publishing sites
  • Switching between latest and older versions of PnP PowerShell
  • Migrating simple data in lists ( e.g. lookup lists)
  • Handle external lists
  • Migrate from On-Premises to Office 365
  • … you name what you would like to add to this list

Getting Started

Well the best way to get started is to read the documentation.


Once you’ve created a config.xml, CollectSolution.ps1 will export the sites that you have configured. ApplySolution will then apply all the templates and workarounds needed to create your copy of the site.

Avatar for Pieter Veenstra

By Pieter Veenstra

Business Applications Microsoft MVP working as a Principal Architect at HybrIT Services Ltd. You can contact me using contact@sharepains.com

8 thoughts on “Office 365 – SharePoint – PnP Tenant Migration Sample is now available!”
    1. Hi Nigel,

      You can add multiple lines like this in the config.xml:

      < .... Name="Home Site - Staff Page" Url="" Template="HomeStaffPage" Location="HomeStaffPage" Import="False" Export="True" Handler="PageContent" PageUrl="SitePages/Staff.aspx"

      each line will have a pageUrl for a page that you want to export. During the export the scripts are changing the home page and then set them back afterwards. More details in this document:


      1. Hi Pieter
        My config.xml is :-

        I get two templates one in Tenant Migration > Templates > HomePage and one in Tenant Migration > Templates >HomeTestScrollingText

        Which seem the same except one has one of the ClientSidePages In and the other has the Other ClientSidePage in. Can I not have just one copy of the Template with both ClientSidePages in ?

        If I have Location and Template the same, then I only get the second ClientSidePage.



      2. Hi Nigel,

        You will indeed end up with two templates. One template with the full site and one template with just the custom page ( assuming that you set the handlers that you want tot run to just include page content). Yes not ideal as I’m sure you want multiple pages in one template but having said that I haven’t found it to difficult to merge the templates manually. Alternatively, applying both templates isn’t too bad either.

  1. Hi Pieter
    Thanks for this.
    If I set Handler = “PageContent” in both <Web ….. XML Elements then I get two templates almost the same with the only difference being the ClientSidePage.

    IS that right or have I got the Handler wrong in one of them ?



  2. Hi Pieter

    I am getting a provisioning template of a list which contains a person field.

    I am using
    foreach($fieldValue in $listItem.FieldValues.GetEnumerator())
    $fieldName = $fieldValue.Key
    if ($fieldName -ne “” -and $fieldName -ne $null)

    $dataXml += “”
    $dataXml += $fieldValue.Value
    $dataXml += “”


    I am getting Microsoft.SharePoint.Client.FieldUserValue rather than the person themselves.

    Any Ideas what is wrong with the PowerShell ?



Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from SharePains by Microsoft MVP Pieter Veenstra

Subscribe now to keep reading and get access to the full archive.

Continue Reading

%d bloggers like this: