Modifying content type field properties




A SharePoint site column has a number of properties which, as a developer, you may need to alter. These properties include Name, Type, ShowInEditForm, ShowInDisplayForm, Hidden etc. Some of these properties can be changed once at the site column level and the changes can be propagated to all lists in the site collection. This is surfaced in the UI for a selection of properties:

Using the SharePoint UI to propagate field property changes to all lists
Using the SharePoint UI to propagate field property changes to all lists

The same (with the ability to set many more properties) can be achieved with PowerShell (or, as always, in C#):

$site = Get-SPSite $siteUrl
$field = $site.RootWeb.Fields[$fieldName]
# set field properties
$field.ShowInDisplayForm = $false
# update field - pass in true to push changes to lists
$field.Update($true) 

The properties that are not listed in the UI may not “update all list columns based on this site column” as you would expect if you are using content types. Content types have a collection of field references (or links) to the list columns which get updated, but the links themselves have their own set of properties which override those set for the list field. This means that if you run the PowerShell snippet above, any existing content types which reference that field will continue to show the field on edit forms. To get around this issue, one must update the content types individually. The PowerShell script below is an example of how you might achieve this.

# Set variables
$webAppUrl = "http://XXX"
$fieldInternalName = "MyFavouriteField"
$listNames = @("Official Documents", "Liaison Statements")
$contentTypeNames = @("OD Document", "CR Document", "LS Document")
 
Write-Host "Hiding field '$fieldInternalName' from display forms" -NoNewline
 
# Get Site Column
$site = Get-SPSite $webAppUrl
if($site -eq $null)
{
  throw "Failed to find site by url: $webAppUrl"
}
 
foreach($web in $site.AllWebs)
{
  try
  {
    foreach($listName in $listNames)
    {
      $list = $web.Lists.TryGetList($listName)
      if($list -ne $null)
      {
        foreach($ctName in $contentTypeNames)
        {
          $ct = $list.ContentTypes[$ctName]
          if($ct -ne $null)
          {
            $updateCt = $false
            $field = $ct.FieldLinks[$fieldInternalName]
            if($field -ne $null)
            {
              # Update field properties
              $showInDisplayForm = $false
              if($field.ShowInDisplayForm -ne $showInDisplayForm)
              {
                $field.ShowInDisplayForm = $showInDisplayForm
                $updateCt = $true
              }
            }
            if($updateCt)
            {
              $ct.Update()
              Write-Host "." -NoNewline -ForegroundColor Green
            }
            else
            {
              Write-Host "." -NoNewline -ForegroundColor Cyan
            }
          }
        }
      }
    }
  }
  catch [System.Exception]
  {
    $errorMessage = $Error[0]
    Write-Host ""
    Write-Host "Failed on $($web.Url), $errorMessage" -ForegroundColor Red
  }
  finally
  {
    $web.Dispose()
  }
}
$site.Dispose()
Write-Host " done" -ForegroundColor Green

This is all pretty obvious when you really think about it. It is a necessity to allow for the flexibility of content types on a list to handle list data in their own way.




2 thoughts on “Modifying content type field properties”

    1. The script is embedded as a gist (https://gist.github.com/). It is possible that if you are reading this article via a feed reader or news aggregator, or perhaps an unsupported browser, that the gist will not be rendered. I’ll look into this, but in the meantime please try viewing this article via a desktop browser. Cheers, Paul.

Leave a Reply

Your email address will not be published.