Why PnP- Provisioning -
1. As sandbox solution is going to get deprecated as server side code is not recommended for office 365 sharepoint online sites to deploy artefacts to Sharepoint online.
2. No Code Sandbox solution (js or csom code) cannot have too much of control while deployment process.
3. In certain scenario when you want to only deploy certain files or termsets or any other artefact.
4. Monitoring can be done for each and every deployment step.
Scenario :
Dev site on office 365 and now want to move that to QA or any other environment. But here, you will need to create lot of term sets, fields, content types, lists, groups , master pages, pages layouts and etc manually.
So for the above scenario one of the way would be to use the pnp provisioning schema for deployment. Here in the below example Console application is used. All the dlls used are either from PnP-Provisioning (please check git hub link) or from sharepoint client object model.
Only user having access to sharepoint admin site can create term sets or other settings at the tenancy level.

1. As sandbox solution is going to get deprecated as server side code is not recommended for office 365 sharepoint online sites to deploy artefacts to Sharepoint online.
2. No Code Sandbox solution (js or csom code) cannot have too much of control while deployment process.
3. In certain scenario when you want to only deploy certain files or termsets or any other artefact.
4. Monitoring can be done for each and every deployment step.
Scenario :
Dev site on office 365 and now want to move that to QA or any other environment. But here, you will need to create lot of term sets, fields, content types, lists, groups , master pages, pages layouts and etc manually.
So for the above scenario one of the way would be to use the pnp provisioning schema for deployment. Here in the below example Console application is used. All the dlls used are either from PnP-Provisioning (please check git hub link) or from sharepoint client object model.
Only user having access to sharepoint admin site can create term sets or other settings at the tenancy level.
The standard process “Office365 Developer Patterns and
Practices” [PnP] is used in the deployment process. PnP provides the tools and
functions to export the XML schema from an existing Office 365 SharePoint
online site. This XML schema contains the PnP nodes and attributes.
Sample XML Schema is as below

Reference
Below steps will explain how to migrate artefacts / content from dev to QA site.
1. Get xml schema from source site containing artefacts Term sets, Fields, Content types, lists and etc.
a. Create a console application in visual studio.
b. Download all the necessary dlls and source code from GIT HUB link.
c. Add below code to get the XML from your site.
using System;
using Microsoft.SharePoint.Client;
using System.Security;
using OfficeDevPnP.Core.Framework.Provisioning.Model;
using OfficeDevPnP.Core.Framework.Provisioning.ObjectHandlers;
using OfficeDevPnP.Core.Framework.Provisioning.Connectors;
using OfficeDevPnP.Core.Framework.Provisioning.Providers.Xml;
namespace PnPDemo
{
class GetSchema
{
static void Main(string[] args)
{
Console.WriteLine("Enter the Sharepoint Online Site URL : ");
string webUrl = Console.ReadLine();
Console.WriteLine("Enter the username : ");
string username = Console.ReadLine();
Console.WriteLine("Enter Password : ");
SecureString password = GetPasswordFromConsoleInput();
Console.WriteLine("Enter the Sharepoint Online Destination Site URL : ");
Console.ReadLine();
GetProvisioningTemplate(webUrl, username, password);
Console.ReadLine();
}
private static void GetProvisioningTemplate(string webUrl, string username, SecureString password)
{
using (var context = new ClientContext(webUrl))
{
context.Credentials = new SharePointOnlineCredentials(username, password);
Web web = context.Web;
context.Load(web, w => w.Title);
context.ExecuteQueryRetry();
Console.WriteLine("Your Site Title is: " + context.Web.Title);
ProvisioningTemplateCreationInformation ptci = new ProvisioningTemplateCreationInformation(web); //Images and other files will get deployed
ptci.BaseTemplate = web.GetBaseTemplate();
ptci.FileConnector = new FileSystemConnector(String.Format(@"{0}\..\..\", AppDomain.CurrentDomain.BaseDirectory), "");
ptci.PersistBrandingFiles = true;
ptci.PersistPublishingFiles = true;
ptci.IncludeAllTermGroups = true;
ptci.IncludeSiteCollectionTermGroup = true;
ptci.IncludeAllTermGroups = true;
ptci.IncludeSiteGroups = true;
ptci.IncludeNativePublishingFiles = true;
ptci.ProgressDelegate = delegate (String message, Int32 progress, Int32 total)
{
Console.WriteLine("{0:00}/{1:00} - {2}", progress, total, message);
};
ProvisioningTemplate template = web.GetProvisioningTemplate(ptci); // Get all the data from source site to destination site
XMLTemplateProvider provider = new XMLFileSystemTemplateProvider(String.Format(@"{0}\..\..\", AppDomain.CurrentDomain.BaseDirectory), "");
provider.SaveAs(template, "YourProvisioningXML.xml");
}
}
private static SecureString GetPasswordFromConsoleInput()
{
ConsoleKeyInfo info;
//Get user password as securestring
SecureString securePassword = new SecureString();
do
{
info = Console.ReadKey(true);
if (info.Key != ConsoleKey.Enter)
{
securePassword.AppendChar(info.KeyChar);
}
} while (info.Key!=ConsoleKey.Enter);
return securePassword;
}
}
}
After execution of the code, xml like below will generate which can be used to apply it to destination site.
2. Add below method to apply provisioning to destination site.
private static bool ApplyProvisioningTemplate(string webUrl, string username, SecureString password, XmlNode XMLTemplate)
{
using (var context = new ClientContext(webUrl))
{
try
{
context.Credentials = new SharePointOnlineCredentials(username, password);
Web web = context.Web;
context.Load(web, w => w.Title);
context.ExecuteQueryRetry();
XMLTemplateProvider provider = new XMLFileSystemTemplateProvider(String.Format(@"{0}\..\..\", AppDomain.CurrentDomain.BaseDirectory), "");
int Total = XMLTemplate.SelectNodes("XMLTemplateName").Count;
int Count = 1;
foreach (XmlNode XMLTemplateName in XMLTemplate)
{
ProvisioningTemplate template = provider.GetTemplate(XMLTemplateName.InnerText);
ProvisioningTemplateApplyingInformation ptai = new ProvisioningTemplateApplyingInformation();
ptai.ProgressDelegate = delegate (String message, Int32 progress, Int32 total)
{
Console.WriteLine("Executing Step {0:00}/{1:00},{2}", Count, Total, PrintMessages(message));
StaticLogger.LogMessage(string.Format("Executing Step {0:00}/{1:00},{2}", Count, Total, GetMessageText(message)));
};
template.Connector = provider.Connector; // Selects which files to upload on destination site
web.ApplyProvisioningTemplate(template, ptai);
Count++;
}
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine("\nDeployment Process Failed.");
StaticLogger.LogMessage(ex.Message);
StaticLogger.LogMessage(ex.StackTrace);
StaticLogger.LogMessage("Deployment Process Failed.");
return false;
}
}
}
private static string PrintMessages(string message)
{
string text = message;
switch (message)
{
case "Regional Settings":
text = "Applying Regional Settings";
break;
//Likewise you can add extra messages for each xml node or artefact.
}
return text;
}
you can also try to have configuration XML like below one for configuring number of properties used while applying the schema.


