"Can you make another site exactly like the project site, but for the new client?" In the farm days that meant site templates and feature stapling. In Microsoft 365 the answer is the PnP provisioning engine: extract a fully-configured site into a portable XML template, parameterise it, and apply it to as many new sites as you like — consistently, repeatably, and in source control.
What the engine does
The PnP provisioning engine reads and writes a provisioning template — an XML document (the PnP schema) that describes a site's structure: lists and libraries, content types, site columns, navigation, pages, web parts, permissions, branding, and more. Two halves:
- Extraction — point it at a configured "reference" site and it captures the structure into a template.
- Application — point it at a target site and it provisions everything the template describes.
Extracting a template
With PnP PowerShell, connect to your model site and export it. (In recent PnP.PowerShell the cmdlets are Get-PnPSiteTemplate / Invoke-PnPSiteTemplate; older PnP-PowerShell used Get-PnPProvisioningTemplate / Apply-PnPProvisioningTemplate — same engine, renamed.)
Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/project-model" -Interactive
# Extract the whole site to an XML template
Get-PnPSiteTemplate -Out "ProjectSite.xml"
# Or scope it to just what you want
Get-PnPSiteTemplate -Out "ProjectSite.xml" `
-Handlers Lists, ContentTypes, Fields, Navigation
-Handlers to extract only the parts you care about. A full extract pulls in security, pages, and theming you may not want to redeploy. Scoping the handlers keeps the template small, reviewable, and far less likely to carry environment-specific cruft into the next site.
Parameterising with tokens
A template that hard-codes "Project Alpha" everywhere isn't reusable. The engine supports tokens — placeholders resolved at apply time. You define parameters in the template and reference them as {parameter:Name}, then supply values when you apply:
<!-- inside the template -->
<pnp:Parameters>
<pnp:Parameter Key="ClientName" Required="true" />
<pnp:Parameter Key="ProjectCode" Required="true" />
</pnp:Parameters>
<!-- used later -->
<pnp:Title>{parameter:ClientName} Project Workspace</pnp:Title>
Other built-in tokens resolve site-relative URLs, the site title, term IDs, and more — for example {site}, {siteid}, and {themecatalog} — so the same template works regardless of the target URL.
Applying the template
Connect to a freshly created target site and apply, passing parameter values:
Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/acme-project" -Interactive
Invoke-PnPSiteTemplate -Path "ProjectSite.xml" `
-Parameters @{ "ClientName" = "Acme"; "ProjectCode" = "AC-204" }
The engine is broadly idempotent — re-applying a template updates what exists rather than duplicating it — which makes it safe to re-run when you evolve the template and want to push changes to sites already provisioned.
Site designs & site scripts
The provisioning engine runs when you invoke it. To make a template fire automatically whenever a user creates a site, pair it with site designs and site scripts — the native SharePoint mechanism. A site script is JSON describing actions; a site design groups scripts and appears in the "create site" experience.
The common production pattern: a small site script triggers a webhook/Azure Function (via the triggerFlow action), and that function runs the full PnP template — giving you the rich PnP schema and automatic execution on site creation:
# Register a site script and design with PnP PowerShell
$script = Get-Content "trigger-script.json" -Raw
$siteScript = Add-PnPSiteScript -Title "Apply Project Template" -Content $script
Add-PnPSiteDesign -Title "Project Workspace" `
-SiteScriptIds $siteScript.Id -WebTemplate TeamSite
Where this fits
- Governed self-service — users create sites that come pre-configured to your standards.
- Multi-tenant / multi-client consistency — one template, many identical workspaces.
- Source-controlled structure — the XML template lives in Git; site structure becomes reviewable, diff-able, and deployable through a pipeline.
- Disaster recovery / migration — rebuild a site's structure anywhere from the template.
The provisioning engine is the closest thing modern SharePoint has to "infrastructure as code" for site structure. Capture once, parameterise, version it, and you turn the ad-hoc, click-by-click site build into a repeatable, auditable deployment — exactly the discipline consultants need when every client wants "the same thing, but theirs."