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?
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.
https://github.com/SharePoint/PnP-PowerShell/tree/master/Samples/Tenant.Migration/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.
Hi Pieter, How do I get all of the sitepages in the template ? It only seems to put the welcome page into the template. Just like the OOTB version of get-PnPProvisioningTemplate. I have executed Connect-SPOService -Url https://mytenant-admin.sharepoint.com
Set-SPOSite -Identity https://mytenant.sharepoint.com -DenyAddAndCustomizePages 0
Thanks
Nigel
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:
https://github.com/SharePoint/PnP-PowerShell/blob/master/Samples/Tenant.Migration/Documentation/config.md
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.
Regards
Nigel
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.
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 ?
Thanks
Nigel
That sounds right. I would expect the pages to be different. The rest is the same as the site is the same.
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 ?
Thanks
Nigel
Sorry should be :-
$dataXml += “”
$dataXml += $fieldValue.Value
$dataXml += “”