Site Design Deployment Made Easy

Site Designs have made the deployment of repeatable customisation of sites much easier, and in my opinion are the starting point for any SharePoint deployment for communication or collaboration.

While the capabilities of Site Designs are well documented and continue to evolve, I see many environments where the deployment of the Site Scripts and Site Designs has been done in a way that allows for multiple versions of the same Site Script and Site Design to exist.

I have put together a very basic framework to support the repeatable deployment and upgrade of Site Scripts and Site Designs.

As a starting point the solution consists of the following components:

  • A repository of JSON files for the different Site Scripts
  • A PowerShell module script
  • A connection script
  • A CSV file to define the Site Scripts for a Site Design
  • A script to create the Site Scripts from the CSV and create a Site Designs

File Structure

  • \CPSSiteDesign-Functions
    • CPSSiteDesign-Functions.psm1
  • \CSV
    • Intranet.csv
  • \JSON
    • Common_JoinHubSite.json
    • Common_RegionalSettings.json
  • 01-Connect.ps1
  • 02-CreateSiteDesign-Intranet.ps1


This is a PowerShell module file with three functions in it:


Checks if a Site Script with the same Title exists.

If it does, the JSON content is updated.

If it does not, a new Site Script is created.

The GUID of the Site Script is added to the SiteScripts parameter and returned from the function.


Checks that the Hub Site exists and replaces the ##hubSiteId## token with ID of the Hub Site

Checks if a Site Script with the same Title exists.

If it does, the JSON content is updated.

If it does not, a new Site Script is created.

The GUID of the Site Script is added to the SiteScripts parameter and returned from the function.


Checks if a Site Design with the same Title exists.

If it does, the associated Site Scripts are updated.

If it does not, a new Site Design is created.

The GUID of the Site Design is returned from the function.


This CSV file has four columns that define the parameters that will be used to create the Site Scripts:

  • Title – The title of the Site Script – used to check for existence
  • Description – A description of what the Site Script does
  • File – the relative path and name of the JSON file used to create the Site Script, e.g. \JSON\SiteScripts\Common_JoinHubSite.json
  • HubJoin – Yes or No depending on whether the Site Script needs to find the details of a Hub Site to join

JSON Files

These files follow the JSON schema for creating Site Scripts and can be created using one of the following approaches:


This file is intended to be run first to connect to the tenant and set the $TenantName variable that can then be reused by scripts that create Site Designs.


This is the file that brings it all together.

Remove-Module CPSSiteDesign-Functions
Import-Module -Name ".\CPSSiteDesign-Functions" -Verbose

$ShowDebug = $false
$SiteScripts = @("Remove")
$CSVFile = "\CSV\Intranet.csv"
$CSVPath = $PSScriptRoot + $CSVFile

$hubSiteUrl = "https://$"

$CSV = Import-Csv -Path $CSVPath

foreach ($Row in $CSV) {
    $SiteScriptTitle = $Row.Title
    $SiteScriptDescription = $Row.Description
    $SiteScriptFile = $PSScriptRoot + $Row.File
    $HubJoin = $Row.HubJoin
    if ($ShowDebug) {
        Write-Host "SiteScriptTitle: $SiteScriptTitle" -ForegroundColor Yellow
        Write-Host "SiteScriptDescription: $SiteScriptDescription" -ForegroundColor Yellow
        Write-Host "SiteScriptFile: $SiteScriptFile" -ForegroundColor Yellow
        Write-Host "HubJoin: $HubJoin" -ForegroundColor Yellow

    if ($HubJoin -eq "Yes") {
        $SiteScripts = Set-CPSSiteScriptWithHubJoin `
            -Title $SiteScriptTitle `
            -Description $SiteScriptDescription `
            -File $SiteScriptFile `
            -HubSiteUrl $hubSiteUrl `
            -SiteScripts $SiteScripts `
            -ShowDebug $ShowDebug

    if ($HubJoin -eq "No") {
        $SiteScripts = Set-CPSSiteScript `
            -Title $SiteScriptTitle `
            -Description $SiteScriptDescription `
            -File $SiteScriptFile `
            -SiteScripts $SiteScripts `
            -ShowDebug $ShowDebug

    if ($ShowDebug) {
        Write-Host "Hub: $SiteScripts" -ForegroundColor Yellow

if ($ShowDebug) {
    Write-Host "Remove the initial entry in the Site Scripts array" -ForegroundColor Yellow
$TidySiteScripts = {$SiteScripts}.Invoke()

if ($ShowDebug) {
    Write-Host "Set Site Design" -ForegroundColor Yellow
$SiteDesign = $null
$SiteDesign = Set-CPSSiteDesign `
    -Title "AE - Intranet Site" `
    -Description "Creates an Intranet site" `
    -SiteScripts $TidySiteScripts `
    -WebTemplate "68" `
    -ShowDebug $ShowDebug

if ($ShowDebug) {
    Write-Host "Site Design: $SiteDesign" -ForegroundColor Yellow
Lines 1-2Import the module with the functions
Line 4 Set $ShowDebug to true if diagnostic messages need to be displayed
Line 5 Initialise the Site Scripts array with a value of “Remove” which will be removed later
Line 6 Set the location of the CSV file
Line 7 Import the CSV file
Line 9 If required, set the URL of the Hub Site that will be used in one or more Site Scripts
Line 11 Iterate through the CSV rows
Line 12-15 Retrieve values from the CSV row
Line 24-32 If required, create a Site Script with a reference to a Hub Site
Line 34-41 If required, create a Site Script without a reference to a Hub Site
Line 51-52 Remove the “Remove” element from the array of Site Script Ids
Line 58-63 Create a Site Design


There are many ways that this process can be enhanced but as a starting point for the repeatable deployment of Site Designs, this process has proven to save many hours of effort.


Many of the formats of the files are tricky to upload so the files below have all been suffixed with .txt which should be removed: