SharePoint site designs and site scripts
Neil Haddley • February 15, 2021
SharePoint users and administrators have long appreciated the opportunity to reuse SharePoint Site Templates.
Site scripts
Microsoft site scripts allow users and administrators to automate the provisioning of "similar" SharePoint sites.
Site scripts are JSON formatted files.
Site scripts include "actions" that will modify a SharePoint site.
Site script actions include:
Add Nav Link
Apply ThemeCreate Content TypeCreate Site ColumnCreate SharePoint ListInstall SolutionJoin Hub SiteRemove Nav LinkSet Regional SettingsSet Site BrandingSet Site LogoSet Site External Sharing CapabilityTrigger Flow
The full schema can be downloaded from here
Add-SPOSiteScript
Site scripts are added to a SharePoint tenant using the Add-SPOSiteScript command

Connect to the SharePoint administration site

Load the JSON text into a variable
Add-SPOSiteDesign
Site designs can extend the SharePoint modern team site template(64) or the SharePoint modern communication site template (68).
Site designs are added to a SharePoint tenant using the ADD-SPOSiteDesign command (specifying one or more Site Script ids)

Add the Site Script and add the Site Design
SharePoint Create a Site
Once the Site design has been created the out of the box "Create a Site" user experience will be updated

Select "Team Site" because the new Site Design is based on the team site template(64)

The "Contoso customer tracking" Site Design is available in the "Choose a design" drop down list.

Click the Finish button to create the new Site and to run the Site Scripts

The newly created site includes the "Customer Tracking" list
Applying a site design to an existing site
The Get-SPOSiteDesign command can be used to list the installed Site designs (and the ids assigned).
Site designs can be applied to an existing SharePoint site using the Invoke-SPOSiteDesign command.

Site contents before invoking site design

Invoke-SPOSiteDesign

Site contents after invoking site design
Get-SPOSiteScriptFromWeb
The Get-SPOSiteScriptFromWeb command extracts Site Script from an existing SharePoint site.

Running the Get-SPOSiteScriptFromWeb command
Example site script
JAVASCRIPT
1{ 2 "$schema": "schema.json", 3 "actions": [ 4 { 5 "verb": "createSPList", 6 "listName": "Customer Tracking", 7 "templateType": 100, 8 "subactions": [ 9 { 10 "verb": "setDescription", 11 "description": "List of Customers and Orders" 12 }, 13 { 14 "verb": "addSPField", 15 "fieldType": "Text", 16 "displayName": "Customer Name", 17 "isRequired": false, 18 "addToDefaultView": true 19 }, 20 { 21 "verb": "addSPField", 22 "fieldType": "Number", 23 "displayName": "Requisition Total", 24 "addToDefaultView": true, 25 "isRequired": true 26 }, 27 { 28 "verb": "addSPField", 29 "fieldType": "User", 30 "displayName": "Contact", 31 "addToDefaultView": true, 32 "isRequired": true 33 }, 34 { 35 "verb": "addSPField", 36 "fieldType": "Note", 37 "displayName": "Meeting Notes", 38 "isRequired": false 39 } 40 ] 41 } 42 ], 43 "bindata": { }, 44 "version": 1 45}
Get-SPOSiteScriptFromWeb results
JAVASCRIPT
1{ 2 "$schema": "https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json", 3 "actions": [ 4 { 5 "verb": "createSiteColumnXml", 6 "schemaXml": "<Field ID=\"{c15b34c3-ce7d-490a-b133-3f4de8801b76}\" Name=\"TaskStatus\" Group=\"Core Task and Issue Columns\" Type=\"Choice\" DisplayName=\"Task Status\" SourceID=\"http://schemas.microsoft.com/sharepoint/v3/fields\" StaticName=\"TaskStatus\" DelayActivateTemplateBinding=\"GROUP,SPSPERS,SITEPAGEPUBLISHING\" Customization=\"\" AllowDeletion=\"TRUE\"><CHOICES><CHOICE>Not Started</CHOICE><CHOICE>In Progress</CHOICE><CHOICE>Completed</CHOICE><CHOICE>Deferred</CHOICE><CHOICE>Waiting on someone else</CHOICE></CHOICES><MAPPINGS><MAPPING Value=\"1\">Not Started</MAPPING><MAPPING Value=\"2\">In Progress</MAPPING><MAPPING Value=\"3\">Completed</MAPPING><MAPPING Value=\"4\">Deferred</MAPPING><MAPPING Value=\"5\">Waiting on someone else</MAPPING></MAPPINGS><Default>Not Started</Default></Field>", 7 "pushChanges": true 8 }, 9 { 10 "verb": "createContentType", 11 "name": "To Do Item", 12 "id": "0x0100AC72E73DED8B1947B3AD265DD7CFCB4A", 13 "description": "", 14 "parentId": "0x01", 15 "hidden": false, 16 "group": "Custom Content Types", 17 "subactions": [ 18 { 19 "verb": "addSiteColumn", 20 "internalName": "TaskStatus" 21 } 22 ] 23 }, 24 { 25 "verb": "createSPList", 26 "listName": "To Do", 27 "templateType": 100, 28 "color": "2", 29 "icon": "11", 30 "subactions": [ 31 { 32 "verb": "setDescription", 33 "description": "To Do List" 34 }, 35 { 36 "verb": "addContentType", 37 "name": "To Do Item" 38 }, 39 { 40 "verb": "addSPFieldXml", 41 "schemaXml": "<Field ID=\"{fa564e0f-0c70-4ab9-b863-0177e6ddd247}\" Type=\"Text\" Name=\"Title\" DisplayName=\"Title\" Required=\"TRUE\" SourceID=\"http://schemas.microsoft.com/sharepoint/v3\" StaticName=\"Title\" FromBaseType=\"TRUE\" MaxLength=\"255\" />" 42 }, 43 { 44 "verb": "addSPFieldXml", 45 "schemaXml": "<Field ID=\"{82642ec8-ef9b-478f-acf9-31f7d45fbc31}\" DisplayName=\"Title\" Description=\"\" Name=\"LinkTitle\" SourceID=\"http://schemas.microsoft.com/sharepoint/v3\" StaticName=\"LinkTitle\" Type=\"Computed\" ReadOnly=\"TRUE\" FromBaseType=\"TRUE\" Width=\"150\" DisplayNameSrcField=\"Title\" Sealed=\"FALSE\"><FieldRefs><FieldRef Name=\"Title\" /><FieldRef Name=\"LinkTitleNoMenu\" /><FieldRef Name=\"_EditMenuTableStart2\" /><FieldRef Name=\"_EditMenuTableEnd\" /></FieldRefs><DisplayPattern><FieldSwitch><Expr><GetVar Name=\"FreeForm\" /></Expr><Case Value=\"TRUE\"><Field Name=\"LinkTitleNoMenu\" /></Case><Default><HTML><![CDATA[<div class=\"ms-vb itx\" onmouseover=\"OnItem(this)\" CTXName=\"ctx]]></HTML><Field Name=\"_EditMenuTableStart2\" /><HTML><![CDATA[\">]]></HTML><Field Name=\"LinkTitleNoMenu\" /><HTML><![CDATA[</div>]]></HTML><HTML><![CDATA[<div class=\"s4-ctx\" onmouseover=\"OnChildItem(this.parentNode); return false;\">]]></HTML><HTML><![CDATA[<span> </span>]]></HTML><HTML><![CDATA[<a onfocus=\"OnChildItem(this.parentNode.parentNode); return false;\" onclick=\"PopMenuFromChevron(event); return false;\" href=\"javascript:;\" title=\"Open Menu\"></a>]]></HTML><HTML><![CDATA[<span> </span>]]></HTML><HTML><![CDATA[</div>]]></HTML></Default></FieldSwitch></DisplayPattern></Field>" 46 }, 47 { 48 "verb": "addSPView", 49 "name": "All Items", 50 "viewFields": [ 51 "LinkTitle", 52 "TaskStatus" 53 ], 54 "query": "", 55 "rowLimit": 30, 56 "isPaged": true, 57 "makeDefault": true, 58 "replaceViewFields": true 59 } 60 ] 61 } 62 ] 63}