Provisioning templates are a powerful way to replicate SharePoint site structures. With the PnP Framework, you can capture a template from one site and reapply it to others.
Applying a PnP Provisioning Template from Local Disk to SharePoint Online (C#)
Provisioning templates are a powerful way to replicate SharePoint site structures. With the PnP Framework, you can capture a template from one site and reapply it to others.
In this guide, we’ll focus on the apply phase only: loading a pre-exported XML template from the local disk (c:\pnp\ExportedTemplate.xml) and applying it to a target SharePoint site.
🔹 What this code does
- Loads a PnP XML template stored on disk.
- Connects to a target SharePoint Online site using an access token.
- Applies the template with
ApplyProvisioningTemplate. - Logs progress and messages for each step.
✅ Full Source Code
using System;
using Microsoft.SharePoint.Client;
using PnP.Framework.Provisioning.ObjectHandlers;
using PnP.Framework.Provisioning.Providers.Xml;
namespace PnPConsoleApply
{
internal class TemplateApplier
{
private readonly Action<string> Log;
public TemplateApplier(Action<string> logAction)
{
Log = logAction;
}
public void ApplyTemplate(string targetUrl, string token)
{
try
{
// Hardcoded path to the exported XML template
string templatePath = @"c:\pnp\ExportedTemplate.xml";
Log($"📂 Loading template from {templatePath}...");
// Create provider pointing to c:\pnp
var provider = new XMLFileSystemTemplateProvider(@"c:\pnp", "");
// Load the template by filename
var template = provider.GetTemplate("ExportedTemplate.xml");
using (var tgtCtx = GetContext(targetUrl, token))
{
Log("🧩 Applying template...");
var applyingInfo = new ProvisioningTemplateApplyingInformation
{
ClearNavigation = true,
MessagesDelegate = (msg, type) => Log($"[PnP {type}]: {msg}")
};
tgtCtx.Web.ApplyProvisioningTemplate(template, applyingInfo);
Log("✅ Template applied successfully.");
}
}
catch (Exception ex)
{
Log($"❌ ERROR: {ex.Message}");
if (ex.InnerException != null) Log($"🔎 Inner: {ex.InnerException.Message}");
throw;
}
}
private ClientContext GetContext(string url, string token)
{
var ctx = new ClientContext(url);
ctx.ExecutingWebRequest += (s, e) =>
{
e.WebRequestExecutor.WebRequest.Headers["Authorization"] = "Bearer " + token;
};
return ctx;
}
}
}
🔹 How to use this code
- Make sure you have previously exported a PnP XML template and placed it in:
c:\pnp\ExportedTemplate.xml - Acquire an access token using MSAL (or reuse the authentication helper from your export tool).
- Call the
ApplyTemplatemethod:
var applier = new TemplateApplier(Console.WriteLine);
applier.ApplyTemplate("https://tenant.sharepoint.com/sites/target-site", token);
🔹 Example Output
📂 Loading template from c:\pnp\ExportedTemplate.xml...
🧩 Applying template...
[PnP Information]: Processing Lists
[PnP Information]: Processing Fields
[PnP Information]: Processing Content Types
✅ Template applied successfully.
🔹 Why use local XML
- Debugging-friendly → you can open/edit the XML file directly.
- Predictable → avoids issues with temp directories or blob storage.
- Reusable → one exported XML can be applied to multiple target sites.
🔹 Next Steps
- Combine this with the export tool to complete the workflow: export → save XML → apply.
- Switch to
.pnppackages if you need to include resources like images or scripts. - Automate token retrieval using client credentials flow if running unattended jobs.
