Page templates are really useful for helping content authors to create news and pages, and bringing unified feeling throughout sites, for example in your intranet. Currently, when page template is created, it is stored to SitePages library of the current site and it will be only available there. In many cases organizations need to have unified templates on all sites in a hub or even all available communication sites.

On this blog post I’m focusing of distributing page templates with PnP PowerShell and PnP provisioning templates. Solution can be easily automated with Azure Functions or Runbooks.

First example is distributing templates from a hub site to all sites linked to it. Second example is distributing templates to all communication sites available in your tenant. Authentication to SharePoint Online is made with Azure AD registered application, which uses a client id and a certificate for authentication. That way I don’t need to take care of user-level permissions on SharePoint sites. On Azure AD, Sites.FullControl.All SharePoint permission is granted to the application.

You can find detailed guide how to setup App authentication with certificate in this PnP PowerShell article: https://github.com/pnp/PnP-PowerShell/tree/master/Samples/SharePoint.ConnectUsingAppPermissions

Distributing templates on a SharePoint hub

If you want to distribute same page templates in a hub, most logical place to maintain those templates is the hub site.

#1) Connect to the hub site with app-only authentication

Connect-PnPOnline -Url $hubSiteUrl -Tenant $tenant -ClientId $clientID -Thumbprint $certificateThumbprint

#2) Get a list of sites connected to a hub

You can get a list of sites connected to a hub with Get-PnPHubSiteChild cmdlet. It returns a list of site urls.

$sites = Get-PnPHubSiteChild -Identity $hubSiteUrl

#3) Get templates from a hub site

Page templates are retrieved with a provisioning template including all client side pages.

$basetemplate = Get-PnPProvisioningTemplate -IncludeAllClientSidePages -Handlers PageContents,Pages -OutputInstance -Schema LATEST -PersistBrandingFiles

New template object is created and all client side pages with PromotedAsTemplate property set to true are added to the new template.

$template = New-PnPProvisioningTemplate
foreach($page in $basetemplate.ClientSidePages)
{
     if($page.PromoteAsTemplate -eq $true)
     {
          $template.ClientSidePages.Add($page)
     }
}
#Including images added to a template
$template.Files.AddRange($basetemplate.Files)

#4) Loop through connect sites and apply a template

foreach($site in $sites)
{
    $connection = Connect-PnPOnline -Url $site -Tenant $tenant -ClientId $clientID -Thumbprint $certificateThumbprint -ReturnConnection
    Apply-PnPProvisioningTemplate -InputInstance $template -Connection $connection
   
}

Distributing page templates to all communication sites on the tenant

For distributing templates to all communication sites on your tenant, I suggest creating a separate site for hosting page templates. That could be a same site, where organization asset libraries for images and document templates are hosted.

Process is quite similar as in the first example.

#1) Connect to a site hosting templates

Connect-PnPOnline -Url $templateSiteUrl -Tenant $tenant -ClientId $clientID -Thumbprint $certificateThumbprint

#2) Get all communication sites on your tenant

For getting all communication sites, you need to use Get-PnPTenantSite cmdlet with Template attribute. Site template for communication sites is SITEPAGEPUBLISHING#0.

Get-PnPTenantSite -Template SITEPAGEPUBLISHING#0

#3) Create a provisioning template (as in first example )

$basetemplate = Get-PnPProvisioningTemplate -IncludeAllClientSidePages -Handlers PageContents,Pages -OutputInstance -Schema LATEST
$template = New-PnPProvisioningTemplate
foreach($page in $basetemplate.ClientSidePages)
{
    if($page.PromoteAsTemplate -eq $true)
    {
        $template.ClientSidePages.Add($page)
    }
        
}

foreach($site in $sites)
{
    $connection = Connect-PnPOnline -Url $site -Tenant $tenant -ClientId $clientID -Thumbprint $certificateThumbprint -ReturnConnection
    Apply-PnPProvisioningTemplate -InputInstance $template -Connection $connection
   
}

Afterword

As you can see, distributing page templates with PnP PowerShell is quite simple and requires just few lines of code. When automating page template distribution, remember to communicate it clearly with content authors and stakeholders. They might discover that it’s very useful to modify distributed templates on a site level, for example adding site specific ready-made content on templates. All of these changes are overwritten with this approach. Also when planning centralized distribution of templates, include all stakeholders to planning to getting most suitable set of templates.

You can find both PowerShell script examples from my GitHub repository:

https://github.com/mpaukkon/SharePoint/blob/master/PowerShell/Copy-SharePointPageTemplateFromHub.ps1

https://github.com/mpaukkon/SharePoint/blob/master/PowerShell/Copy-SharePointPageTemplateToCommsSites.ps1