(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).
Sorry, missed this – yeah, we don’t support mms fields yet (at least not elegantly). It’s actively being worked on, so should have more details to share soon. As for the triggerFlow failure (but the job still succeeds) we’re investigating and hope to have a fix out soon. Thanks!
— Sean Squires (@iamseansquires) November 5, 2018
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
- Make sure both of your Fields have a SourceID value
- Make sure the Note field internal name is the value of your Managed Metadata field + “TaxHTField”
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.
I have tried the same way to create the managed metadata fields, it is creating all the fields successfully. But some times only the first column is failed to create, getting an error message Action failed. Do you have any idea about this?
LikeLike
The only time I’ve seen this is if you’ve tried to deploy the site column before already. I’ve stopped manually creating site column now, and I use the new PowerShell and/or REST endpoints to generate my columns.
https://beaucameron.net/2019/01/16/get-site-script-from-list-using-rest/
LikeLiked by 1 person
Thanks Beau for your quick reply. I will try to implement the new approach from your blog. It is very helpful.
LikeLike
Hi Beau, followed the above, but the field doesn’t appear in search results. I doublechecked the SourceID and …TaxHTField suffix… Any thought why they won’t show up?
LikeLike
Hi Michel, are you able to send me the XML you are using for this? I’d be happy to review it for you.
A couple other things to check / do.
1. You can now generate the JSON/XML from a list from a newly created endpoint. You can create the column in a SharePoint list and then run Get-SPOSiteScriptFromList and it will create the JSON/XML perfectly for you. 🙂
2. If the XML is right and it’s still not working, making sure you are a part of a SharePoint Group. There is a bug in Modern that won’t generate managed properties in modern sites https://joannecklein.com/2019/02/08/crawled-managed-properties-and-modern-team-sites/
LikeLike
Hi Beau, just sent you the json using the contact form. I did the Get-SPOSiteScriptFromList and this resulted in a json file. When adding this file as site script and adding this script to a design, it creates the column though no managed/crawled properties are created. Also this cmdlet doesn’t export the note field.
LikeLike
Hi Beau,
Excellent post, Beau. Followed the article to provision site columns (including TaxonomyField) and content types on a Hub site and everything worked fine and even associated site collections got the columns and content types. Created Document library and added those newly created content types to the library and uploaded bunch of documents and added metadata including terms in taxonomy field… awesome so far.
Then we decided to update the site script with new site columns and add those to content types … scripts updated… ran the updated site scripts as site design on all already associated sites. New site columns provisioned and added to content type and changes are propagated to existing document library as well… sweet.
Uploaded a new document in the earlier created document library… and boom all taxonomy fields doesn’t work. The SPListItem being updated was not retrieved with all taxonomy fields.
I’ve looked up couple of articles but doesn’t seem like an apt solution. Hoping you may have some directions on the issue.
Cheers.
LikeLike
Hi Raj, there are some issues with idempotency in Site Scripts when specifying the ID (which is ultimately done in this post). However, I can’t say for certain that is the issue you are seeing.
When you go to the column settings, is the term set selection reset?
LikeLike
Hi Beau,
Thank you for your reply and I did a get workaround for this issue and a solution as well.
The workaround was to go to list settings and open each one of the metadata columns (Edit Column screen) and just Click Ok. This seems to reestablishes the connection of columns with the term store somehow and your fields start to work. Make sure you edit columns from the list settings screen and not going to content type in question and editing the columns there… that doesn’t work somehow. 😐
Ok, talking about solution, I was using “pushChanges”: true for all the managed metadata columns and turning it false in the site script fixed the issue. It seems when you have it enabled (pushchanges = true) it breaks the existing relations within all libraries where that particular site column is used.
I’m not sure whether it’s an issue with my site script or the way I understand the provisioning of metadata columns. The same provisioning settings worked earlier with other development models on premise or Cloud. It certainly is different in cloud with Metadata columns in site script.
Thank you for your help again and keep blogging the awesome stuff!
LikeLike
Hi Beau/Raj,
I’m currently having this issue. The field is connected to the Term Store as I could select the terms available, but the “The SPListItem being updated was not retrieved with all taxonomy fields” error message appears when trying to save the value.
I have tried re-creating the field (through site script), tried the workaround that Raj suggesting (clicking OK on the column in List Settings), and tried clicking OK on the site column. None of them are working. Do you have any other suggestion on how to fix/investigate this issue?
Cheers
Felicia
LikeLike
Hi Felicia, I have seen this error as well… but unfortunately I don’t have a fix for it. I think there were updates that rolled out during this year that have broken this functionality. I have been unable to successfully/continuously deploy Managed Metadata fields
LikeLike
Hi Felicia,
We were able to successfully create these managed metadata fields with Site Scripts as documented in the article above with an exception of “pushChanges”: false. The script still works for our tenant.
Do you mind sharing your site script? I can take a look then.
LikeLike
Nice.. but I have just one feedback for this, something to be aware of.
I wanted my Managed Metadata filed to allow multiple values. So, in the JSON file, I’ve changed Mult=\”FALSE\” to Mult=\”TRUE\”.
And everything worked nicely, but when I’ve added the “Page properties” web part to Modern Page – it didn’t show values.
After all day of investigation – I’ve returned Mult=”FALSE” – and then in Site Pages library I have manually turned on “Allow multiple values” – now “Page properties” are showing multiple values without problems.
LikeLike