{"id":950,"date":"2012-12-25T06:38:36","date_gmt":"2012-12-25T06:38:36","guid":{"rendered":"https:\/\/poiseddevelopers.com\/reality-tech\/?p=950"},"modified":"2024-04-26T12:47:40","modified_gmt":"2024-04-26T12:47:40","slug":"add-a-taxonomy-field-into-every-site-collection-and-to-a-content-type","status":"publish","type":"post","link":"https:\/\/poiseddevelopers.com\/reality-tech\/add-a-taxonomy-field-into-every-site-collection-and-to-a-content-type\/","title":{"rendered":"Add a Taxonomy Field into Every Site Collection and to a Content Type"},"content":{"rendered":"<h4>Add a Taxonomy Field into Every Site Collection<\/h4>\n<p>I recently had to add a Taxonomy Site Column into a range of Site Collections, and then add the new Site Column into a Content Type. \u00a0Lastly, I needed to update all libraries in the site collection to reflect the updated Content Type. \u00a0How might we do this?<\/p>\n<h4>Step by step<\/h4>\n<p>Let\u2019s get a web application, and its sites. \u00a0Note that this is not the most efficient approach, as a collection of SPSites can be large. \u00a0A more efficient way could be to pass the Sites through a pipeline.<\/p>\n<pre lang=\"php\">  $webApp=Get-Spwebapplication \"http :\/\/SharePoint\" #your web app url\r\n$sites=$webApp.sites;<\/pre>\n<p>Let\u2019s loop through the SPSites, and get the SPWeb to work with. \u00a0The SPSite actually has no content, nor does it have Site Columns or Content Types. \u00a0The root web is where Site Columns and Content Types are managed.<\/p>\n<pre lang=\"php\">  for ($i=0; $i -lt $sites.count; $i++)\r\n{\r\n$site= $sites[$i];\r\n$JPweb=$site.rootweb;\r\n}<\/pre>\n<p>To do anything with Managed Metadata requires opening a Taxonomy session. \u00a0 This can be done directly through the Service Application. \u00a0For simplicity, I open the session at the Site level. \u00a0This code assumes only one Managed Metadata Service association (index offset of zero). \u00a0If you have more than one MMS service application, query the collection of termstores to ensure you are grabbing the correct one. \u00a0Note below there is a \u201cgroup name\u201d and \u201cTerm Set Name\u201d required. \u00a0Adjust these to match your environment. \u00a0Lastly there\u2019s a check below to ensure you grabbed a termset, and aren\u2019t holding a null reference:<\/p>\n<div><\/div>\n<pre lang=\"php\">$taxSession = new-object Microsoft.SharePoint.Taxonomy.TaxonomySession($site, $true);\r\n$termStore = $taxSession.TermStores[0];\r\n$TermSet = $termStore.Groups[\"Your Term Group\"].TermSets[\"TermSetName\"]\r\n \r\nif ($TermSet -eq $null)\r\n{\r\nWrite-Host -ForegroundColor DarkRed \"Termset does not exist\"\r\ncontinue;\r\n}<\/pre>\n<p>Now let\u2019s create a new field. Note we\u2019ll need to know the display name for the field, as well as define a static (internal) name. \u00a0As with all Site Columns, I highly recommend using a static name that avoids spaces and other characters that lead to control escape sequences in the code (%20 for space, etc). \u00a0Note the termset that is \u201clatched\u201d to this field refers to the specific term store (it could point to any of your Managed Metadata Service Applications) and to the specific termset. \u00a0These are GUIDs. \u00a0Note that each Managed Metadata Service Application is associated with a dedicated database. \u00a0That\u2019s where your termsets are stored. \u00a0You\u2019ll want to select a \u201cgroup\u201d for where the site column will be displayed. \u00a0We\u2019ll add the field, and update the SPWeb object.<\/p>\n<pre lang=\"php\"> $taxonomyField = $JPweb.Fields.CreateNewField(\"TaxonomyFieldType\", $FieldToAddDisplayName)\r\n$taxonomyField.SspId = $termSet.TermStore.Id\r\n$taxonomyField.TermSetId = $termSet.Id\r\n$taxonomyField.AllowMultipleValues = $false\r\n$taxonomyField.Group = \"Site Column Group\"\r\n$taxonomyField.StaticName = $FieldToAddStaticName\r\n$taxonomyField.ShowInEditForm = $true\r\n$taxonomyField.ShowInNewForm = $true\r\n$taxonomyField.Hidden = $false\r\n$taxonomyField.Required = $false\r\n \r\n$JPweb.Fields.Add($taxonomyField);\r\n$JPweb.Update();<\/pre>\n<p data-uw-rm-sr=\"\">Now let\u2019s grab the set of Content Types, find our target Content Type and field, and update the Content Type. \u00a0We\u2019ll turn off ReadOnly for the Content Type, and do the following special object update to force propagation of the Content Type into all the libraries in the site collection:\u00a0$ct.UpdateIncludingSealedAndReadOnly()<\/p>\n<div><\/div>\n<pre lang=\"php\">$cts=$JPWeb.ContentTypes\r\n$ct=$cts[\"Specific Content Type\"] # replace with your content type\r\n \r\n$ct.set_ReadOnly($false)\r\n$fields=$ct.fields\r\n \r\n$fs=$JPWeb.Fields\r\n$favField=$fs.get_Item($FieldToAddDisplayName)\r\n \r\nif ($favField -eq $null)\r\n{\r\nWrite-Host -ForegroundColor DarkRed \"Cannot find $($FieldToAdd) in web $($JPWeb.url)\"\r\ncontinue;\r\n}\r\n \r\n$link = new-object Microsoft.SharePoint.SPFieldLink $favField\r\n$ct.FieldLinks.Add($link)\r\n$ct.UpdateIncludingSealedAndReadOnly($true)\r\n$ct.set_ReadOnly($true)<\/pre>\n<p>Let\u2019s now put it all together into one neat script that includes some extra error handling:<\/p>\n<pre lang=\"php\"> $FieldToAddStaticName = \"InternalFieldName\"\r\n$FieldToAddDisplayName = \"Field Display Name\"\r\n$webApp=Get-Spwebapplication \"http :\/\/SharePoint\" #your web app url\r\n$sites=$webApp.sites;\r\n \r\nfor ($i=0; $i -lt $sites.count; $i++)\r\n{\r\n$site= $sites[$i];\r\n$JPweb=$site.rootweb;\r\n \r\nif ($site.url -notlike \"http :\/\/SharePoint\/MyPreferredPath\/*\")\r\n{\r\ncontinue;\r\n}\r\n \r\n$taxSession = new-object Microsoft.SharePoint.Taxonomy.TaxonomySession($site, $true);\r\n$termStore = $taxSession.TermStores[0];\r\n $TermSet = $termStore.Groups[\"Your Term Group\"].TermSets[\"TermSetName\"]\r\n \r\nif ($TermSet -eq $null)\r\n{\r\nWrite-Host -ForegroundColor DarkRed \"Termset does not exist\"\r\ncontinue;\r\n}\r\n \r\n$taxonomyField = $JPweb.Fields.CreateNewField(\"TaxonomyFieldType\", $FieldToAddDisplayName)\r\n \r\n$taxonomyField.SspId = $termSet.TermStore.Id\r\n $taxonomyField.TermSetId = $termSet.Id\r\n $taxonomyField.AllowMultipleValues = $false\r\n $taxonomyField.Group = \"Site Column Group\"\r\n $taxonomyField.StaticName = $FieldToAddStaticName\r\n $taxonomyField.ShowInEditForm = $true\r\n $taxonomyField.ShowInNewForm = $true\r\n $taxonomyField.Hidden = $false\r\n $taxonomyField.Required = $false\r\n \r\n$JPweb.Fields.Add($taxonomyField);\r\n \r\n$JPweb.Update();\r\n$cts=$JPWeb.ContentTypes\r\n$ct=$cts[\"Specific Content Type\"] # replace with your content type\r\nif ($ct -eq $null)\r\n{\r\nWrite-Host -ForegroundColor DarkRed \"Cannot add field to Content Type in web $($JPWeb.url)\"\r\ncontinue;\r\n}\r\n \r\n$ct.set_ReadOnly($false)\r\n$fields=$ct.fields\r\n \r\n$fs=$JPWeb.Fields\r\n$favField=$fs.get_Item($FieldToAddDisplayName)\r\n \r\nif ($favField -eq $null)\r\n{\r\nWrite-Host -ForegroundColor DarkRed \"Cannot find $($FieldToAdd) in web $($JPWeb.url)\"\r\ncontinue;\r\n}\r\n \r\n$link = new-object Microsoft.SharePoint.SPFieldLink $favField\r\n \r\n$ct.FieldLinks.Add($link)\r\n \r\n$ct.UpdateIncludingSealedAndReadOnly($true)\r\n \r\n$ct.set_ReadOnly($true)\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Add a Taxonomy Field into Every Site Collection I recently had to add a Taxonomy Site Column into a range of Site Collections, and then add the new Site Column into a Content Type. \u00a0Lastly, I needed to update all libraries in the site collection to reflect the updated Content Type. \u00a0How might we do [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":951,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[39],"tags":[],"class_list":["post-950","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-content-types"],"acf":[],"_links":{"self":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/950","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/comments?post=950"}],"version-history":[{"count":1,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/950\/revisions"}],"predecessor-version":[{"id":962,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/950\/revisions\/962"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/media\/951"}],"wp:attachment":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/media?parent=950"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/categories?post=950"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/tags?post=950"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}