What is the way to apply custom templates to a modern sharepoint online site ideally in code

Copper Contributor

Please can some one advise on the best way to apply a custom design template from one sharepoint to another , so that the copy has the same lists, interface and security.  I am trying to create a site ('MyNewsite')  & apply a design to it ('My Source Site'), and have hit a number of problems 

 

I have the SharePoint Administrator role enabled

I have looked at the UI , CSOM & PNP.Powershell

 

SharePoint online native UI behaves as follows

A number of discussions mention clicking on an option in the UI called 'Apply A Site Template', behind the cog icon.  I cannot see this option. 

 

CSOM code

var Designs = tenant.GetSiteDesigns();
ctx.Load(existingDesigns);
ctx.ExecuteQuery();

var desiredDesign = Designs.FirstOrDefault(d => d.Title == "My Source Site");

var results = tenant.ApplySiteDesign("MyTenant.sharepoint.com/sites/MyNewsite", desiredDesign.Id);
ctx.Load(results);
.ctx.ExecuteQueryRetry();

 

This code runs, but does not apply the design to MyTenant.sharepoint.com/sites/MyNewsite

 

PNP.Powershell V1.12.0

$webUrl="MyTenant.sharepoint.com/sites/MyNewsite"

Connect-PnPOnline -Url $webUrl -Interactive -ForceAuthentication -verbose
Invoke-PnPSiteTemplate -Path C:\myFolder\PnPtemplate.xml -Parameters @{"SiteUrl"=$webUrl}

 

This code runs, and echos all sorts of changes to the screen , but again when I open MyTenant.sharepoint.com/sites/MyNewsite, it shows the old design. 

 

Please advise on a working method to do this, many thanks in advance. 

 

Best regards, Richard 

 

 

 

7 Replies

Script 1:

 

Connect-PnPOnline -Url $OldSiteURL -Interactive
Get-PnPSiteTemplate -Out template.xml

 

 

Script 2:

 

#Config Variables
$TemplateXML ="template.xml"


#Connect to PnP Online
Connect-PnPOnline -Url $NewSiteURL -Interactive


#Apply provisioning Template
Invoke-PnPSiteTemplate -path $TemplateXML

 

 

 

@NicolasKheirallah  Many thanks for the reply.  The GetPnPSiteTemplate & the InvokePnPSiteTemplate is one of the combinations I tried.   The Invoke appears to run through without any errors echoed back.  Its just that after the event, nothing changes in the target site. 

 

Do you know what might cause that behaviour? 

 

Thanks again 

Run InvokePnPSiteTemplate in -Verbose and see where it fails!
Hi @NicolasKheirallah. Thank you again for the reply. With the verbose parameter, the invoke-PNPSiteTemplate runs through as before, echoing various 'applying template' quickly messages to the application screen ( not the dos-like command window) , and something is changing on the target site because I get duplicate 'Home' links across the top of the site, as the script runs, but no list or colour scheme changes , and if there are any error messages, then they disappear too quickly to see . If I deliberately put a typo in the command / script , then those do persist in the command window. Thanks again for your help. Is there a way to route the verbose messages to a log file ?
Hi @NicholasKeirallah. Thank you . This has created a tracelog with an error in it telling me that a View is Invalid.
How do I know what View is the problem, & what its problem is?
[Error] ExecuteQuery threw following exception: Microsoft.SharePoint.Client.ServerException: The specified view is invalid.
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream)
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse()
at Microsoft.SharePoint.Client.ClientRequest.<ExecuteQueryToServerAsync>d__53.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.SharePoint.Client.ClientRequest.<ExecuteQueryAsync>d__39.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.SharePoint.Client.ClientRuntimeContext.<ExecuteQueryAsync>d__65.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.SharePoint.Client.ClientContext.<ExecuteQueryAsync>d__28.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.SharePoint.Client.ClientContextExtensions.<ExecuteQueryImplementation>d__6.MoveNext()
ServerErrorCode: -2147024809
ServerErrorTypeName: System.ArgumentException

Thanks again
Hi @NicolasKheirallah . Thanks for this. The log has highlighted a corrupt view. Is there a way to find out which view, and what is wrong with it ?
[Error] ExecuteQuery threw following exception: Microsoft.SharePoint.Client.ServerException: The specified view is invalid.
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream)
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse()
at Microsoft.SharePoint.Client.ClientRequest.<ExecuteQueryToServerAsync>d__53.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.SharePoint.Client.ClientRequest.<ExecuteQueryAsync>d__39.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.SharePoint.Client.ClientRuntimeContext.<ExecuteQueryAsync>d__65.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.SharePoint.Client.ClientContext.<ExecuteQueryAsync>d__28.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

Thanks again