How to find which site designs have been applied on a SharePoint site.

In SharePoint Online, a new provisioning process is being used which allows an administrator to define a set of designs that can be applied to a newly created site. These site designs consist of the ability add column, lists, specify themes, apply SPFx solutions and more.

It’s important to note that multiple site designs can be applied to a site in SharePoint online.

How site designs can be applied to a site collection

  • During creation of a new site using the SharePoint UI
  • During the association to a hub site
  • Invoking on an existing site using Invoke-SPOSiteDesign and Add-SPOSiteDesignTask

Because site designs can be applied in multiple ways and more than one site design can be applied to a site, an admin may want to have a way to see which site designs have been invoked onto a site.

Introducing Get-SPOSiteDesignRun (PowerShell)

Get-SPoSiteDesignRun is a new command available to the SharePoint Online Management Shell that will show which site designs have been applied to a specific site collection.

$siteDesignsRan = Get-SPOSiteDesignRun -WebUrl "https://yoursite.sharepoint.com/sites/testsite"

Id                : e4ff3264-c7b1-4121-b179-445382216703
SiteDesignId      : d082fc0e-9a49-4675-88ac-d49e0931670e
WebId             : 42a2b14c-ce2a-485e-8854-92d3b334704f
SiteId            : f848c5a3-9c6b-40f6-becd-8c5661f0e558
SiteDesignVersion : 1
SiteDesignTitle   : Long Site Design

Id                : 8efb3528-3ff1-4dcf-98a3-7f020492a79f
SiteDesignId      : d082fc0e-9a49-4675-88ac-d49e0931670e
WebId             : 42a2b14c-ce2a-485e-8854-92d3b334704f
SiteId            : f848c5a3-9c6b-40f6-becd-8c5661f0e558
SiteDesignVersion : 1
SiteDesignTitle   : Long Site Design

Id                : 00000000-0000-0000-0000-000000000000
SiteDesignId      : 7da58b45-b11d-4e3c-940b-a96c925d02be
WebId             : 42a2b14c-ce2a-485e-8854-92d3b334704f
SiteId            : f848c5a3-9c6b-40f6-becd-8c5661f0e558
SiteDesignVersion : 1
SiteDesignTitle   : MMD Test

Notice the first two site designs that were run, are actually the same. This is because not only does this command show all site designs applied, it also shows the history of invocations against this site collection. Using Invoke-SPOSiteDesign or Add-SPOSiteDesignTask. More information on Add-SPOSiteDesignTask can be found in my previous post.

Needing more information

Get-SPOSiteDesignRun is a valuable command, but as an administrator you may not know what each site design has implemented and the history of actions taken in the site collection. To do this, you can use the new Get-SPOSiteDesignRunStatus command and it will return the result of each action from every site script in your site design.

In the command above, I got a list of site designs that have been invoked onto a site collection and stored them in an object called $siteDesignsRan. I can use the Get-SPOSiteDesignRunStatus command to find more information about each site design invocation.

Get-SPOSiteDesignRunStatus -Run $siteDesignsRan[1]

OrdinalIndex    : 0
SiteScriptID    : 0aa8ce3a-0a7f-4963-bd0f-07ce28a6a5dd
SiteScriptTitle : LongSiteScript
SiteScriptIndex : 0
ActionIndex     : 0
ActionTitle     : Create site column MyTestMMD2TaxHTField through XML
ActionKey       : 00000000-0000-0000-0000-000000000000
OutcomeCode     : Success
OutcomeText     : 

OrdinalIndex    : 1
SiteScriptID    : 0aa8ce3a-0a7f-4963-bd0f-07ce28a6a5dd
SiteScriptTitle : LongSiteScript
SiteScriptIndex : 0
ActionIndex     : 1
ActionTitle     : Create site column MyTestMMD2 through XML
ActionKey       : 00000000-0000-0000-0000-000000000000
OutcomeCode     : Success
OutcomeText     : 

OrdinalIndex    : 2
SiteScriptID    : 0aa8ce3a-0a7f-4963-bd0f-07ce28a6a5dd
SiteScriptTitle : LongSiteScript
SiteScriptIndex : 0
ActionIndex     : 2
ActionTitle     : Create content type Test CT
ActionKey       : 00000000-0000-0000-0000-000000000000
OutcomeCode     : NoOp
OutcomeText     : 

OrdinalIndex    : 3
SiteScriptID    : 0aa8ce3a-0a7f-4963-bd0f-07ce28a6a5dd
SiteScriptTitle : LongSiteScript
SiteScriptIndex : 0
ActionIndex     : 2
ActionTitle     : Add site column MyTestMMD2 to content type
ActionKey       : 00000000-0000-0000-0000-000000000000
OutcomeCode     : NoOp
OutcomeText     : 

OrdinalIndex    : 4
SiteScriptID    : 0aa8ce3a-0a7f-4963-bd0f-07ce28a6a5dd
SiteScriptTitle : LongSiteScript
SiteScriptIndex : 0
ActionIndex     : 2
ActionTitle     : Add site column MyTestMMD2TaxHTField to content type
ActionKey       : 00000000-0000-0000-0000-000000000000
OutcomeCode     : NoOp
OutcomeText     : 

OrdinalIndex    : 5
SiteScriptID    : 0aa8ce3a-0a7f-4963-bd0f-07ce28a6a5dd
SiteScriptTitle : LongSiteScript
SiteScriptIndex : 0
ActionIndex     : 3
ActionTitle     : Create or update list Custom List
ActionKey       : 00000000-0000-0000-0000-000000000000
OutcomeCode     : NoOp
OutcomeText     : List with name Custom List already exists.

OrdinalIndex    : 6
SiteScriptID    : 0aa8ce3a-0a7f-4963-bd0f-07ce28a6a5dd
SiteScriptTitle : LongSiteScript
SiteScriptIndex : 0
ActionIndex     : 3
ActionTitle     : Add content type Test CT
ActionKey       : 00000000-0000-0000-0000-000000000000
OutcomeCode     : NoOp
OutcomeText     :

This is a great command that should be in every admin’s toolbox to help manage and govern SharePoint sites. It gives us a very clear history of what actions have been taken on a given site collection and the results of those actions.

If you ever have a question as to which site designs have been applied to your site, look no further than Get-SPOSiteDesignRun and Get-SPOSiteDesignRunStatus.

Using REST

The previous example was showing how to get the Site Designs applied using PowerShell.  Below is how you can get the results using REST.

Get a list of Site Designs ran on a site using REST

(GET) _api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignRun

Result

 
   "d": 
      "results": 
          
            "__metadata": 
               "id":"https://testsite.sharepoint.com/sites/test/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteDesignRun4eb4e8b2-ead5-4f11-a4f9-0d127b898740",
               "uri":"https://testsite.sharepoint.com/sites/test/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteDesignRun4eb4e8b2-ead5-4f11-a4f9-0d127b898740",
               "type":"Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteDesignRun"
            },
            "ID":"38ef12db-e8b8-4716-96d9-7556c61bf98b",
            "SiteDesignID":"6ebda32f-c2dc-4353-b09c-36df6652dfaa",
            "SiteDesignTitle":"Team Site Design",
            "SiteDesignVersion":1,
            "SiteID":"b6e1bf12-151e-43c7-a889-df7d1759db0f",
            "StartTime":"1535557919000",
            "WebID":"e0a62834-f04f-4f31-b2e1-6c8badf56167"
         }
      ]
   }
}

Get Information about a specific site design using REST

Using the response from the above request, you can grab the ID and pass it as the “runId” parameter to the following endpoint.

(POST) _api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignRunStatusAndSchema
fetch("https://testsite.sharepoint.com/sites/test/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignRunStatusAndSchema", {
    "credentials": "include",
    "headers": {
        "accept": "application/json;odata=verbose",
        "accept-language": "en-US,en;q=0.9",
        "content-type": "application/json;odata=verbose",
        "x-requestdigest": "YourXRequestDigest"
    },
    "referrer": "https://testsite.sharepoint.com/sites/test",
    "referrerPolicy": "no-referrer-when-downgrade",
    "body": "{\"runId\":\"38ef12db-e8b8-4716-96d9-7556c61bf98b\"}",
    "method": "POST",
    "mode": "cors"
});

Result

 
   "d": 
      "GetSiteDesignRunStatusAndSchema": 
         "__metadata": 
            "type":"Microsoft.SharePoint.Utilities.WebTemplateExtensions.SPSiteScriptStatusAndSchema"
         },
         "ActionStatus": 
            "__metadata": 
               "type":"Collection(Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptActionStatus)"
            },
            "results": 
                
                  "ActionIndex":0,
                  "ActionKey":"00000000-0000-0000-0000-000000000000",
                  "ActionTitle":"Apply theme Black and Yellow",
                  "LastModified":"1535557920000",
                  "OrdinalIndex":0,
                  "OutcomeCode":0,
                  "OutcomeText":null,
                  "SiteScriptID":"72673672-3708-415d-b7f9-5322288dfa6c",
                  "SiteScriptIndex":0,
                  "SiteScriptTitle":"Apply Theme"
               }
            ]
         },
         "Schema":"{\"recipes\":[{\"actions\":[{\"stages\":[\"Apply theme Black and Yellow\"]}],\"recipeGuid\":\"72673672-3708-415d-b7f9-5322288dfa6c\",\"recipeName\":\"Apply Theme\"}],\"siteDesignTitle\":\"Team Site Design\",\"siteDesignVersion\":1}"
      }
   }
}

 

Hope this helps!

Overcome the 30 action site script limitation in SharePoint Online

This blog post pertains to invoking site designs using PowerShell and not through the SharePoint UI. Increasing the 30 action limit through the UI/UX will be supported soon!

During Ignite in Orlando this year, I had the pleasure to see Sean Squires present on the the latest and greatest features for site provisioning in SharePoint Online. He spoke about some of the future updates coming that will help get over some of the limitations of site designs and site scripts.

What 30 action limit?

When site designs and site scripts were first released, there was a limit of 30 actions that could be used in a site script. These actions include:

  • Creating a content type
  • Creating a list
  • Adding a content type to a list
  • creating list columns
  • setting regional settings
  • deploying SPFx solutions
  • and more…

That means if you started using site scripts when they were first released and you needed to deploy a large amount of customization, you’d have to do this with PowerShell and Azure Functions using the “triggerFlow” action.

Introducing Add-SPOSiteDesignTask

During Ignite, Sean announced that new PowerShell commandlets would be available to increase this limitation from 30 to an extremely high number (100k characters apparently). The release of this has seemingly gone under the radar, but is now available for use!

Add-SPOSiteDesignTask is meant to replace the existing Invoke-SPOSiteDesign. The command is used to apply an already publishing site design to any target site collection. This means there is still a limit of 30 actions when creating sites from the SharePoint UI.

However, unlike Invoke-SPOSiteDesign, the command doesn’t run the site design immediately, instead the site design invocation is put into a schedule to run.

Testing it out

I’ve created a basic site design and site script that run 30+ actions onto a SharePoint site collection. The site script will create 33 site columns, a custom list and apply the columns to the list.

$script = @'
  {
                  "$schema": "schema.json",
                   "actions": [
                            {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn1",
                                "displayName": "Test Column1",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn2",
                                "displayName": "Test Column2",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn3",
                                "displayName": "Test Column3",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn4",
                                "displayName": "Test Column4",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn5",
                                "displayName": "Test Column5",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn6",
                                "displayName": "Test Column6",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn7",
                                "displayName": "Test Column7",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn8",
                                "displayName": "Test Column8",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn9",
                                "displayName": "Test Column9",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn10",
                                "displayName": "Test Column10",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn11",
                                "displayName": "Test Column11",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn12",
                                "displayName": "Test Column12",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn13",
                                "displayName": "Test Column13",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn14",
                                "displayName": "Test Column14",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn15",
                                "displayName": "Test Column15",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn16",
                                "displayName": "Test Column16",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn17",
                                "displayName": "Test Column17",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn18",
                                "displayName": "Test Column18",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn19",
                                "displayName": "Test Column19",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn20",
                                "displayName": "Test Column20",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn21",
                                "displayName": "Test Column21",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn22",
                                "displayName": "Test Column22",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn23",
                                "displayName": "Test Column23",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn24",
                                "displayName": "Test Column24",
                                "isRequired": false
                               }, {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn25",
                                "displayName": "Test Column25",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn26",
                                "displayName": "Test Column26",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn27",
                                "displayName": "Test Column27",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn28",
                                "displayName": "Test Column28",
                                "isRequired": false
                               }, {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn29",
                                "displayName": "Test Column29",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn30",
                                "displayName": "Test Column30",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn31",
                                "displayName": "Test Column31",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn32",
                                "displayName": "Test Column32",
                                "isRequired": false
                               },
                                {
                                "verb": "createSiteColumn",
                                "fieldType": "Text",
                                "internalName": "testColumn33",
                                "displayName": "Test Column33",
                                "isRequired": false
                               },
                        {
                           "verb": "createContentType",
                           "name": "Test CT",
                           "description": "custom content type",
                           "parentName": "Item",
                           "hidden": false,
                           "subactions": [                         
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn1"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn2"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn3"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn4"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn5"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn6"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn7"
                               },{
                               "verb": "addSiteColumn",
                               "internalName":"testColumn8"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn9"
                               },{
                               "verb": "addSiteColumn",
                               "internalName":"testColumn10"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn11"
                               },{
                               "verb": "addSiteColumn",
                               "internalName":"testColumn12"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn13"
                               },{
                               "verb": "addSiteColumn",
                               "internalName":"testColumn14"
                               },{
                               "verb": "addSiteColumn",
                               "internalName":"testColumn15"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn16"
                               },{
                               "verb": "addSiteColumn",
                               "internalName":"testColumn17"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn18"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn19"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn20"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn21"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn22"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn23"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn24"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColum25"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn26"
                               },{
                               "verb": "addSiteColumn",
                               "internalName":"testColumn27"
                               },
                              {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn28"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn29"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn30"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn31"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn32"
                               },
                               {
                               "verb": "addSiteColumn",
                               "internalName":"testColumn33"
                               },
                               
                            ]
                       },
                       {
                        "verb": "createSPList",
                        "listName": "Custom List",
                        "templateType": 100,
                        "subactions": [
                           {
                            "verb": "addContentType",
                            "name": "Test CT"
                           }                      
                         ]
                        }
            
              
                   ],
                   "bindata": { },
               "version": 1
              }
              
              }

}
'@

I have added this site script to SharePoint using the Add-SPOSiteScript command and subsequently added the site script to a new site design using Add-SPOSiteDesign.

Add-SPOSiteScript -Title "LongSiteScript" -Description "Long Site Script" -Content $script
-returned id = 0aa8ce3a-0a7f-4963-bd0f-07ce28a6a5dd

Add-SPOSiteDesign -Title "Long Action Site Design" -WebTemplate "0" -SiteScripts "0aa8ce3a-0a7f-4963-bd0f-07ce28a6a5dd" -Description "Long Action Test"
-return id = d082fc0e-9a49-4675-88ac-d49e0931670e

Using Add-SPOSiteDesignTask

Now that I have created a long site script and the associated site design, it’s time to run the site design on an existing site. I will invoke the site design using Add-SPOSiteDesignTask and passing in the WebUrl and the SiteDesignId from my new site design.

Add-SPOSiteDesignTask -SiteDesignId d082fc0e-9a49-4675-88ac-d49e0931670e -WebUrl https://yourtenantsite.sharepoint.com/sites/testlongscript

After invoking the command, PowerShell is going to output some information for you. It will provide the ID of the new task as well as the associated site design that was provisioned.

Add-SPOSiteDesignTask -SiteDesignId d082fc0e-9a49-4675-88ac-d49e0931670e -WebUrl https://yourtenantsite.sharepoint.com/sites/testlongscript

Id : e4ff3264-c7b1-4121-b179-445382216703
SiteDesignId : d082fc0e-9a49-4675-88ac-d49e0931670e
WebId : 42a2b14c-ce2a-485e-8854-92d3b334704f
SiteId : f848c5a3-9c6b-40f6-becd-8c5661f0e558
LogonName : i:0#.f|membership|beau@cameronsoft.onmicrosoft.com

Checking the results

After waiting a minute or so, I was able to see the reflected changes in my environment.

ContentType

To learn more about Add-SPOSiteDesignTask, the documentation can be found here.

Deploy Managed Metadata fields using site designs and site scripts

(Notice: This post may show unsupported methods for provisioning fields)

You may be in a scenario where you want to create Managed Metadata columns using modern provisioning. This post is going to outline a method that can be used to provision Managed Metadata columns using site designs. Site designs are a new model for provisioning assets (fields,content types, lists, etc…) in modern SharePoint. Information on site designs and site scripts can be found here.

Multiple ways to create columns

Using a site script,  you can create both list and site columns using two different actions — “addSPField” and “addSiteColumn”. The first will deploy a list column and the second action will deploy a site column. However, these two actions only support basic field types in SharePoint. These field types include:

  • Text
  • Note
  • Number
  • Boolean
  • User
  • DateTime

Complex columns such as people fields and managed metadata fields need to be created using the Field Element definition. Using site designs and site scripts, we can provision complex fields using the Field definition with the addSPFieldXml and createSiteColumnXML actions.

There are many ways you can get the Field definition after they have been created in the SharePoint UI. Here are a couple options you could use to export out the schema XML for a list and get the field definitions.

https://yoursite/_vti_bin/owssvr.dll?Cmd=ExportList&List={YOUR_LIST_GUID}

You could also use PnP PowerShell to export out the schema

 $list = Get-PnPList -Identity "your list" -Includes SchemaXml
 $schema = $list.SchemaXml

Which complex fields are supported?

If look through the site script documentation you may notice, it doesn’t actually define which field types are supposed through XML. In regards to a complex field such as a Managed Metadata field, we took to twitter to see if Microsoft had any input. Sean Squires mentioned that currently they do not support Managed Metadata Fields, at least in an elegant way (which to me means, if it works great! if it doesn’t…it’s not officially supported).

How it can be achieved

Managed Metadata Fields are complex fields that actually require two fields to be deployed in order to function properly. One field is a TaxonomyFieldType and another is a Note field. This means we actually have to deploy two fields during the provisioning process.

When you export out a list schema and find your Managed Metadata field, you’ll notice it references the Note field using the ID of the Note field in the TextField node. You may also notice there are tokens for properties such as WebId, SiteId, ListId in your Field definition. In order for the deployment of the field to work we need to remove these token properties.

Secondly, we’ll need to update the <Property> nodes inside the <Customziation> node for the following properties.

  • SspId
  • TermSetId
  • AnchorId

By default, these properties may be using braces to identify the GUID for the Term store, Term set and Anchor. We need to remove the braces and leave the rest of the GUID string.

Here is an example of a cleaned up XML for a Managed Metadata field. Notice how I have removed the {braces} from around the GUIDs for SspdId, TermSetId and AnchorId (in bold).

<Field Type="TaxonomyFieldType" Name="MyTestMMD" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="MyTestMMD" DisplayName="My Test Tax" Group="Test group" ShowField="Term1033" Required="FALSE" EnforceUniqueValues="FALSE" Mult="FALSE"> <Default /> <Customization> <ArrayOfProperty> <Property> <Name>SspId</Name> <Value xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns:q1="http://www.w3.org/2001/XMLSchema" p4:type="q1:string">1ba8a7c0-a373-4bb7-8ee0-2d130933743a</Value> </Property> <Property> <Name>GroupId</Name> <Value xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns:q2="http://www.w3.org/2001/XMLSchema" p4:type="q2:string">0e8f395e-ff58-4d45-9ff7-e331ab728beb</Value> </Property> <Property> <Name>TermSetId</Name> <Value xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns:q2="http://www.w3.org/2001/XMLSchema" p4:type="q2:string">487ba508-4fba-49f1-be4f-ceee2624da0a</Value> </Property> <Property> <Name>TextField</Name> <Value xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns:q6="http://www.w3.org/2001/XMLSchema" p4:type="q6:string">{44a5d269-ce40-4a8f-b0d6-6b7bcb95ff71}</Value> </Property> <Property> <Name>AnchorId</Name> <Value xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns:q3="http://www.w3.org/2001/XMLSchema" p4:type="q3:string">00000000-0000-0000-0000-000000000000</Value> </Property> <Property> <Name>IsPathRendered</Name> <Value xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns:q7="http://www.w3.org/2001/XMLSchema" p4:type="q7:boolean">false</Value> </Property> <Property> <Name>IsKeyword</Name> <Value xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns:q8="http://www.w3.org/2001/XMLSchema" p4:type="q8:boolean">false</Value> </Property> <Property> <Name>Open</Name> <Value xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns:q5="http://www.w3.org/2001/XMLSchema" p4:type="q5:boolean">false</Value> </Property> </ArrayOfProperty> </Customization> </Field>

A couple notes

If you fail to do this successfully, it may look like your column is working. However, SharePoint will not create managed or crawled properties correctly, thus making your column not searchable.

Final site script actions

The next thing we want to do is escape the XML so can we can use it inside a JSON site script. Then finally, we can add the Field definitions to our site script using the “createSiteColumnXml” action.

Here is an example of the two site script actions required to deploy a Managed Metadata field using site designs.

 {
   "verb": "createSiteColumnXml",  
    "schemaXml": "<Field ID=\"{44a5d269-ce40-4a8f-b0d6-6b7bcb95ff71}\" SourceID=\"http:\/\/schemas.microsoft.com\/sharepoint\/v3\" Type=\"Note\" Name=\"MyTestMMDTaxHTField\" StaticName=\"MyTestMMDTaxHTField\" DisplayName=\"MyTestMMDTaxHTField\" Group=\"Test group\" ShowInViewForms=\"FALSE\" Required=\"FALSE\" Hidden=\"TRUE\" CanToggleHidden=\"TRUE\" />"  
 },   
 {  
  "verb": "createSiteColumnXml",  
  "schemaXml": "<Field Type=\"TaxonomyFieldType\" Name=\"MyTestMMD\" SourceID=\"http:\/\/schemas.microsoft.com\/sharepoint\/v3\" StaticName=\"MyTestMMD\" DisplayName=\"My Test Tax\" Group=\"Test group\" ShowField=\"Term1033\" Required=\"FALSE\" EnforceUniqueValues=\"FALSE\" Mult=\"FALSE\"> <Default></Default> <Customization> <ArrayOfProperty> <Property> <Name>SspId</Name> <Value xmlns:q1=\"http://www.w3.org/2001/XMLSchema\" p4:type=\"q1:string\" xmlns:p4=\"http://www.w3.org/2001/XMLSchema-instance\">1ba8a7c0-a373-4bb7-8ee0-2d130933743a</Value> </Property> <Property> <Name>GroupId</Name> <Value xmlns:q2=\"http://www.w3.org/2001/XMLSchema\" p4:type=\"q2:string\" xmlns:p4=\"http://www.w3.org/2001/XMLSchema-instance\">0e8f395e-ff58-4d45-9ff7-e331ab728beb</Value> </Property> <Property> <Name>TermSetId</Name> <Value xmlns:q2=\"http://www.w3.org/2001/XMLSchema\" p4:type=\"q2:string\" xmlns:p4=\"http://www.w3.org/2001/XMLSchema-instance\">487ba508-4fba-49f1-be4f-ceee2624da0a</Value> </Property> <Property> <Name>TextField</Name> <Value xmlns:q6=\"http://www.w3.org/2001/XMLSchema\" p4:type=\"q6:string\" xmlns:p4=\"http://www.w3.org/2001/XMLSchema-instance\">{44a5d269-ce40-4a8f-b0d6-6b7bcb95ff71}</Value> </Property> <Property> <Name>AnchorId</Name> <Value xmlns:q3=\"http://www.w3.org/2001/XMLSchema\" p4:type=\"q3:string\" xmlns:p4=\"http://www.w3.org/2001/XMLSchema-instance\">00000000-0000-0000-0000-000000000000</Value> </Property> <Property> <Name>IsPathRendered</Name> <Value xmlns:q7=\"http://www.w3.org/2001/XMLSchema\" p4:type=\"q7:boolean\" xmlns:p4=\"http://www.w3.org/2001/XMLSchema-instance\">false</Value> </Property> <Property> <Name>IsKeyword</Name> <Value xmlns:q8=\"http://www.w3.org/2001/XMLSchema\" p4:type=\"q8:boolean\" xmlns:p4=\"http://www.w3.org/2001/XMLSchema-instance\">false</Value> </Property> <Property> <Name>Open</Name> <Value xmlns:q5=\"http://www.w3.org/2001/XMLSchema\" p4:type=\"q5:boolean\" xmlns:p4=\"http://www.w3.org/2001/XMLSchema-instance\">false</Value> </Property> </ArrayOfProperty> </Customization> </Field>"  
  },

You can see a full site script in this Gist.

Caveats & “uh ohs”

Using the site script actions above, you should be able to successfully create Managed Metadata fields using site designs. Just be aware that if you see some negative impacts when provisioning these…they are not fully supported by Microsoft.