SharePoint Online content types in Powershell: Edit
SharePoint Online content types in Powershell: Add
SharePoint Online content types in Powershell: Get
List of default properties
Description
Returns the context that is associated with the client object. (Inherited from ClientObject.)
The context can only be retrieved, and not set (no set method on the object).
Gets or sets a description of the content type.
Gets or sets a value that specifies the name of a custom display form template to use for list items that have been assigned the content type.
Gets or sets a value that specifies the URL of a custom display form to use for list items that have been assigned the content type.
Gets or sets a value that specifies the file path to the document template used for a new list item that has been assigned the content type.
Gets a value that specifies the URL of the document template assigned to the content type.
Gets or sets a value that specifies the name of a custom edit form template to use for list items that have been assigned the content type.
Gets or sets a value that specifies the URL of a custom edit form to use for list items that have been assigned the content type.
Gets the column (also known as field) references in the content type.
Gets a value that specifies the collection of fields for the content type.
Gets or sets a value that specifies the content type group for the content type.
Gets or sets a value that specifies whether the content type is unavailable for creation or usage directly from a user interface.
Gets a value that specifies an identifier for the content type. The ContentTypeId type is the identifier for the specified content type. The identifier is a string composed of hexadecimal characters. The identifier must be unique relative to the current site collection and site, and must follow the pattern of prefixing a ContentTypeId with its parent ContentTypeId.
Gets or sets the JSLink for the content type custom form template.
Gets or sets a value that specifies the name of the content type.
Gets or sets a value that specifies the name of a custom new form template to use for list items that have been assigned the content type.
Gets or sets a value that specifies the URL of a custom new form to use for list items that have been assigned the content type.
Gets the object data for the current client object. (Inherited from ClientObject.)
Gets the parent content type of the content type.
Tracks how a client object is created in the ClientRuntimeContext class so that the object can be recreated on the server. This member is reserved for internal use and is not intended to be used directly from your code. (Inherited fromClientObject.)
Gets or sets a value that specifies whether changes to the content type properties are denied.
Gets a value that specifies the XML Schema representing the content type.
Gets a non-localized version of the XML schema that defines the content type.
Gets a value that specifies a server-relative path to the content type scope of the content type.
Gets or sets whether the content type can be modified.
Gets the server object and returns null if the server object is null. (Inherited from ClientObject.)
A string representation of the value of the Id.
Gets or sets data that is associated with the client object. (Inherited from ClientObject.)
Gets a value that specifies the collection of workflow associations for the content type.
*
Source: https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.contenttype_properties.aspx*
Powershell vs User Interface
Many, if not most, of the above mentioned properties can be modified via User Interface. Powershell, however, offers more options and more possibilities for multiple and concurrent updates.
For the sake of brevity all scripts below refer EITHER to list content types OR site content types. You modify one into the other by replacing
$ctx.web.Contenttypes
with
$ctx.web.lists.getbytitle("title").Contenttypes
or vice versa. If you need to modify several or one of the content types and are wondering how to retrieve them, please refer to the previous part of the article: SharePoint Online content types in Powershell: Get.
Description
UserInterface
The description property can get or set the description of the content type. In order to view or modify it from the User Interface, you need to go to
- List>>List Settings>>Content Types>>Choose the content type>> Settings: Name and description for the list content types
- Site Settings>> Site Content Types >> Choose the Content type>> Settings: Name and description for site content types
Powershell
This example sets description of a single content type belonging to a list and retrieved by its name.
- Having installed SharePoint Online SDK, open Powershell ISE. In order to modify the content type we need its name or ID and a list it belongs to. Let us declare all the variables and refer the SDK libraries:
# Paths to SDK. Please verify location on your computer.
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
# Insert the credentials and the name of the admin site
$Username="admin@tenant.onmicrosoft.com"
$AdminPassword=Read-Host -Prompt "Password" -AsSecureString
$AdminUrl="https://tenant.sharepoint.com/sites/powie1"
$ListTitle="MultipleItems"
$Description="My crazy Powershell description"
$ContentTypeName="From Powershell directly to list"
- Load the content types of the list.
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.ExecuteQuery()
$ctx.Load($ctx.Web)
$ll=$ctx.Web.Lists.GetByTitle($ListTitle)
$ctx.Load($ll)
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
- Find the one you are looking for.
foreach($cc in $ll.ContentTypes)
{
if($cc.Name -eq $ContentTypeName)
{
// code coming here
}
}
- Modify the description and update the content type with the new settings. The Boolean value in .Update() method refers to whether the child content types should be updated as well. Since I am modifying a list content type added only to this list, and it does not have any child content types, the Bool is set to $false.
foreach($cc in $ll.ContentTypes)
{
if($cc.Name -eq $ContentTypeName)
{
Write-Host $cc.Name
$cc.Description=$Description
$cc.Update($false)
$ctx.ExecuteQuery()
}
}
Powershell by GUID
This example sets description of a single content type at a site collection level and retrieved by its GUID.
- Declare all the variables and refer the paths to SDK.
# Paths to SDK. Please verify location on your computer.
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
# Insert the credentials and the name of the admin site
$Username="admin@tenant.onmicrosoft.com"
$AdminPassword=Read-Host -Prompt "Password" -AsSecureString
$AdminUrl="https://tenant.sharepoint.com/sites/powie1"
$Description="My crazy Powershell description2"
$ContentTypeGUID="0x0116006288692BD2247D48BA5D55B164C79F51"
- Load the specific content type and write its name to verify if we entered the correct GUID and retrieved the desired content type.
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.ExecuteQuery()
$ctx.Load($ctx.Web)
$cc=$ctx.Web.ContentTypes.GetByID($ContentTypeGUID)
$ctx.Load($cc)
$ctx.ExecuteQuery()
Write-Host $cc.Name
- Update the description.
$cc.Description=$Description
$cc.Update($true)
$ctx.ExecuteQuery()
DisplayFormTemplateName
This property gets or sets a value that specifies the name of a custom display form template to use for list items that have been assigned the content type. For an item Content Type this form is called ListForm. We can check the default forms associated with our list content types using:
$ll=$ctx.Web.Lists.GetByTitle($ListTitle)
$ctx.Load($ll)
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
foreach($cc in $ll.ContentTypes)
{
Write-Host $cc.DisplayFormTemplateName
}
Content types and their default DisplayFormTemplateName
Using script you can also pull the list of default content types from ContentTypeHub and their associated DisplayFormTemplateNames:
Name
DisplayFormTemplateName
System
Common Indicator Columns
Fixed Value based Status Indicator
SimpleKpiDisplayForm
SharePoint List based Status Indicator
SharePointKpiDisplayForm
Excel based Status Indicator
ExcelKpiDisplayForm
SQL Server Analysis Services based Status Indicator
AnalysisServicesKpiDisplayForm
Item
ListForm
Circulation
New Word
ListForm
Category
ListForm
Site Membership
ListForm
Community Member
ListForm
WorkflowServiceDefinition
ListForm
Health Analyzer Rule Definition
ListForm
Resource
FacilitiesForm
HiddenColumn
ListForm
Official Notice
Phone Call Memo
ListForm
Project Policy
ListForm
Holiday
ListForm
What's New Notification
ListForm
WorkflowServiceSubscription
ListForm
Timecard
ListForm
Resource Group
FacilitiesForm
Rule
ListForm
Health Analyzer Report
ListForm
Users
Document
DocumentLibraryForm
Display Template
DocumentLibraryForm
Display Template Code
DocumentLibraryForm
JavaScript Display Template
DocumentLibraryForm
Report
RptLibraryForm
Office Data Connection File
DocumentLibraryForm
List View Style
DocumentLibraryForm
Rich Media Asset
DocumentLibraryForm
Video Rendition
DocumentLibraryForm
Audio
DocumentLibraryForm
Image
DocumentLibraryForm
Web Part Page with Status List
RptLibraryForm
Universal Data Connection File
DocumentLibraryForm
Design File
DocumentLibraryForm
InfoPath Form Template
DocumentLibraryForm
Form
DocumentLibraryForm
Picture
DocumentLibraryForm
Unknown Document Type
DocumentLibraryForm
Master Page
DocumentLibraryForm
Master Page Preview
DocumentLibraryForm
User Workflow Document
DocumentLibraryForm
Wiki Page
WikiEditForm
Basic Page
DocumentLibraryForm
Web Part Page
DocumentLibraryForm
Link to a Document
DocumentLibraryForm
Dublin Core Columns
DocumentLibraryForm
Event
ListForm
Reservations
ListForm
Schedule and Reservations
ListForm
Schedule
ListForm
Issue
ListForm
Announcement
ListForm
Link
ListForm
Contact
ListForm
Custom Contact
ListForm
Message
ListForm
Task
TaskForm
Workflow Task (SharePoint 2013)
TaskForm
Workflow Task
TaskForm
SharePoint Server Workflow Task
TaskForm
Administrative Task
TaskForm
Workflow History
ListForm
Person
ListForm
SharePointGroup
ListForm
DomainGroup
ListForm
Post
BlogForm
Comment
ListForm
East Asia Contact
ListForm
Folder
ListForm
RootOfList
ListForm
Discussion
ListForm
Summary Task
ListForm
Document Collection Folder
ListForm
Document Set
ListForm
System Media Collection
ListForm
Video
ListForm
Custom Video
ListForm
Full script
function Get-SPOContentType
{
param (
[Parameter(Mandatory=$true,Position=1)]
[string]$Username,
[Parameter(Mandatory=$true,Position=2)]
$AdminPassword,
[Parameter(Mandatory=$true,Position=3)]
[string]$Url
)
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.Load($ctx.Web.ContentTypes)
$ctx.ExecuteQuery()
foreach($cc in $ctx.Web.ContentTypes)
{
Write-Host $cc.Name " " $cc.DisplayFormTemplateName
}
$ctx.Dispose()
}
# Paths to SDK. Please verify location on your computer.
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
# Insert the credentials and the name of the admin site
$Username="admin@tenant.onmicrosoft.com"
$AdminPassword=Read-Host -Prompt "Password" -AsSecureString
$AdminUrl="https://tenant.sharepoint.com/sites/contenttypehub"
Get-SPOContentType -Username $Username -AdminPassword $AdminPassword -Url $AdminUrl
The script has been packaged and is available for download at Github.
Modify the Name
The name can be modified, but careless modifications may lead to some issues and the item may no longer be viewable. Below you will find results of modifying a ListForm in an Item Content type into various other forms.
- Default behaviour
- When set to a made-up name
$cc.DisplayFormTemplateName="DifferentForm"
$cc.Update($false)
$ctx.ExecuteQuery()
- DocumentLibraryForm
$cc.DisplayFormTemplateName="DocumentLibraryForm"
The behaviour and display issues presented above are by design and stem from the incompatibility of the forms with the date included in the Item Content Type. Once we use a compatible form, the item will display without issues.
Full Script
function Set-SPOContentType
{
param (
[Parameter(Mandatory=$true,Position=1)]
[string]$Username,
[Parameter(Mandatory=$true,Position=2)]
$AdminPassword,
[Parameter(Mandatory=$true,Position=3)]
[string]$Url,
[Parameter(Mandatory=$true,Position=4)]
[string]$ListTitle
)
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.ExecuteQuery()
$ctx.Load($ctx.Web)
$ll=$ctx.Web.Lists.GetByTitle($ListTitle)
$ctx.Load($ll)
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
foreach($cc in $ll.ContentTypes)
{
Write-Host $cc.Name $cc.DisplayFormTemplateName
$cc.DisplayFormTemplateName="DocumentForm"
$cc.Update($false)
$ctx.ExecuteQuery()
}
$ctx.Dispose()
}
The script has been packaged and is available for download at Technet Gallery. Click here to start download.
Reset to Default
Having both the list of default Template Names and
Verify
First I run the check using default names from a csv file:
$listy=$ctx.Web.Lists
$ctx.Load($listy)
$ctx.ExecuteQuery()
$defaultoweFormaty=Import-Csv C:\Users\ivo\Desktop\Book1.csv
Write-Host $defaultoweFormaty[5].DisplayFormTemplateName
foreach($ll in $listy)
{
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
foreach($cc in $ll.ContentTypes)
{
$opo=$defaultoweFormaty | where {$_.Name -eq $cc.Name}
Write-Host $ll.Title -ForegroundColor Green
Write-Host $opo.DisplayFormTemplateName
Write-Host $cc.DisplayFormTemplateName
Write-Host "----------------------------------------------------"
# $cc.DisplayFormTemplateName="DocumentLibraryForm"
# $cc.Update($false)
# $ctx.ExecuteQuery()
}
}
Of course the check can be modified to return only the content types or lists where the template name has been changed, but since I have only a few lists, I can visually see that indeed some of them have been changed, as a result of my previous tests probably, and may require fixing.
Set
$listy=$ctx.Web.Lists
$ctx.Load($listy)
$ctx.ExecuteQuery()
$defaultoweFormaty=Import-Csv C:\Users\ivo\Desktop\Book1.csv
foreach($ll in $listy)
{
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
foreach($cc in $ll.ContentTypes)
{
$opo=$defaultoweFormaty | where {$_.Name -eq $cc.Name}
Write-Host $ll.Title -ForegroundColor Green
Write-Host $cc.Name
Write-Host $opo.DisplayFormTemplateName
Write-Host $cc.DisplayFormTemplateName
if($opo.DisplayFormTemplateName -ne "")
{
$cc.DisplayFormTemplateName=$opo.DisplayFormTemplateName
$cc.Update($false)
$ctx.Load($cc)
$ctx.ExecuteQuery()
}
Write-Host $ll.Title -ForegroundColor Green
Write-Host $cc.Name
Write-Host $opo.DisplayFormTemplateName
Write-Host $cc.DisplayFormTemplateName
Write-Host "----------------------------------------------------"
}
}
Full scripts
The scripts have been packaged into .ps1 files and are available for download at Technet Gallery:
Verify the content types used in your lists against the default ones
Reset default content types
DisplayFormUrl
DisplayForm
The Display Form is a way of displaying an item. It can be very simple, consisting only of the item title or it can be a complex, customized creation, with links, tips, multiple varied fields and pictures:
.DisplayFormUrl
As per definition the property gets or sets a value that specifies the URL of a custom display form to use for list items that have been assigned the content type. That means that trying to retrieve the url of a default form does not give us any results.
$ctx.Load($ctx.Web)
$ll=$ctx.Web.Lists.GetByTitle($ListTitle)
$ctx.Load($ll)
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
foreach($cc in $ll.ContentTypes)
{
Write-Host $cc.Name $cc.DisplayFormUrl
}
The result is different on a newinfopathlist where a Custom form was deployed
The *~list/Item/displayifs.aspx *is the url of the custom form that the list is using for adding new items.
This makes it very easy to e.g. find all custom forms deployed on all the lists in your site:
foreach($cc in $ll.ContentTypes)
{
if($cc.DisplayFormUrl -ne "")
{
Write-Host "Content type name: "$cc.Name
Write-Host "The Custom url: " $cc.DisplayFormUrl
}
}
Fall back to default
This property allows us also to retract our changes and turn to the default form in case something went wrong with the Custom form and items are no longer viewable:
The script below changes the display form of all content types called ITEM (so basically all items in a list) in all lists in one site to the default one:
foreach($ll in $ctx.Web.Lists)
{
Write-Host $ll.Title -ForegroundColor Green
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
foreach($cc in $ll.ContentTypes)
{
if($cc.Name -eq "Item")
{
$cc.DisplayFormUrl=""
$cc.Update($false)
$ctx.ExecuteQuery()
}
}
}
Ta-daa! The results are immediately visible:
Full scripts
The scripts have been packaged into reusable function and are available for download on the Technet Gallery:
SharePoint Online: Get the custom form display url using Powershell
Find Custom Display Forms Deployed on your lists using Powershell
Unable to view items: modify the DisplayFormUrl back to default one
Document Template
Gets or sets a value that specifies the file path to the document template used for a new list item that has been assigned the content type.
DocumentTemplateUrl
Is a read-only property and cannot be set.
FieldLinks and Fields
Columns are represented as either Field or FieldRef Element (ContentType) elements in the various SharePoint schemas, such as site, list, and content type definitions[1]. The columns are represented as Field elements in site and list definitions. However, the column references are represented as FieldRef Element (ContentType) elements in content type definitions[1]. In simple words SPFields are fields themselves, while SPFieldLinks are references to the fields[2].
It stems from the fact that Lists and Webs contain the actual fields with field data. A content type, on the other hand, only holds Field Reference, which simply points at the corresponding field in the list or web. As argued in MSDN:
The SPFieldCollection object provides developers a way to get a combined view of a column's attributes, as they exist in that content type. Each SPField object represents all the attributes of a column, or field, definition, merged with those attributes that have been overridden in the field reference for that content type.
When you access a SPField in a content type, SharePoint Foundation merges the field definition with the field reference, and returns the resulting SPField object to you. This prevents developers from having to look up a field definition, and then look up all the attributes in the field definition that are overridden by the field reference for that content type.
Because of this, there is a 1-to-1 correlation between the items in the SPFieldLinkCollection and SPFieldCollection objects. For each SPFieldLink object that you add to a content type, SharePoint Foundation adds a corresponding SPField object that represents the combined view of that column as it is defined in the content type.
Comparison of Field Names and Field Link Names of the content types from a Content Type Hub where the names different.
ContentType
Field Title
FieldInternalName
Field Link
Circulation
Append-Only Comments
V3Comments
Comments
Phone Call Memo
Append-Only Comments
V3Comments
Comments
Display Template
Comments
Comments
Description
Display Template Code
Comments
Comments
Description
JavaScript Display Template
Comments
Comments
Description
InfoPath Form Template
Content Type ID
CustomContentTypeId
CusomContentTypeId
User Workflow Document
Visibility
NoCodeVisibility
Visibility
Event
Start Time
StartDate
EventDate
Event
Description
Comments
Description
Reservations
Start Time
StartDate
EventDate
Reservations
Description
Comments
Description
Schedule and Reservations
Start Time
StartDate
EventDate
Schedule and Reservations
Description
Comments
Description
Schedule
Start Time
StartDate
EventDate
Schedule
Description
Comments
Description
Issue
Due Date
TaskDueDate
DueDate
Message
Discussion Title
DiscussionTitleLookup
DiscussionSubjectLookup
Message
Shortest Thread-Index Id Lookup
ShortestThreadIndexIdLookup
ShortestThreadIndexLookup
Task
Due Date
TaskDueDate
DueDate
Task
Task Status
TaskStatus
Status
Workflow Task (SharePoint 2013)
Due Date
TaskDueDate
DueDate
Workflow Task (SharePoint 2013)
Task Status
TaskStatus
Status
Workflow Task (SharePoint 2013)
Instance Id
WF4InstanceId
WorkflowInstanceId
Workflow Task
Due Date
TaskDueDate
DueDate
Workflow Task
Task Status
TaskStatus
Status
Workflow Task
Related Content
WorkflowLink
Link
SharePoint Server Workflow Task
Due Date
TaskDueDate
DueDate
SharePoint Server Workflow Task
Task Status
TaskStatus
Status
SharePoint Server Workflow Task
Related Content
WorkflowLink
Link
Administrative Task
Action
AdminTaskAction
Action
Administrative Task
Description
AdminTaskDescription
Description
Administrative Task
Order
AdminTaskOrder
Priority
Administrative Task
Task Status
TaskStatus
Status
Administrative Task
Due Date
TaskDueDate
DueDate
Workflow History
Description
DLC_Description
Description
Discussion
Shortest Thread-Index Id Lookup
ShortestThreadIndexIdLookup
ShortestThreadIndexLookup
Summary Task
Task Status
TaskStatus
Status
Summary Task
Due Date
TaskDueDate
DueDate
Document Set
Description
DocumentSetDescription
Description
The list is just an excerpt including all DIFFERENT names. The full comparison is available in SharePoint Online content types in Powershell: Fields vs Field Links.
Adding
When you try to add to the FieldCollection of a list, site or content type hub ContentType, an error will be returned:
This functionality is unavailable for field collections not associated with a list.
This is due to the fact that Columns are included in content types by reference, rather than directly.[3] This might be a bit confusing, because content types have both an SPFieldLinkCollection and an SPFieldCollection. The SPFieldLinkCollection is used in the actual definition of the content type, and is what you would want to use in your situation of copying a content type from one web to another. SPFieldLinks correspond to the actual elements in the XML Schema for a content type. Comparatively, when you call on a content type's SPFieldCollection and retrieve a Field from it, what is actually happening is that the content type is checking the corresponding field reference, and then looking up in the list/web to get the actual field. Basically, think of the SPFieldCollection in the same way a lookup works: it is worthless without both the lookup value and the lookup source.[4] To sum up:
Use the FieldLinks property to access the collection of column references in the specified content type. This method returns an SPFieldLinkCollection object.
Use the Add method to add a column reference to the content type.
The example below adds an existing site column to aIl list content types in a particular list. The sealed content types will return an error. Performance is not taken into consideration.
First I have retrieved the site columns names, using
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.Load($ctx.Web.Fields)
$ctx.ExecuteQuery()
foreach($ff in $ctx.Web.Fields)
{Write-Host $ff.InternalName}
and from numerous results chose KpiStatus as a column to be added to my current Item Content Type at a list level.
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.Load($ctx.Web.Lists)
$ll=$ctx.Web.Lists.GetByTitle($ListTitle)
$ctx.Load($ll)
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
$field=$ctx.Web.Fields.GetByInternalNameOrTitle($SiteColumn)
foreach($cc in $ll.ContentTypes)
{
$link=new-object Microsoft.SharePoint.Client.FieldLinkCreationInformation
$link.Field=$field
$cc.FieldLinks.Add($link)
$cc.Update($false)
$ctx.ExecuteQuery()
}
As expected, the sealed content type "Folder" returned an error.
The added Field (Column) is immediately visible as Indicator Status under Content Type Columns:
The field (column) is automatically added to the list columns:
And there is appropriate field adjacent to our created fieldlink with the same ID
Full Script
param (
[Parameter(Mandatory=$true,Position=1)]
[string]$Username,
[Parameter(Mandatory=$true,Position=2)]
$AdminPassword,
[Parameter(Mandatory=$true,Position=3)]
[string]$Url,
[Parameter(Mandatory=$true,Position=3)]
[string]$ListTitle,
[Parameter(Mandatory=$true,Position=3)]
[string]$SiteColumn
)
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.Load($ctx.Web.Lists)
$ll=$ctx.Web.Lists.GetByTitle($ListTitle)
$ctx.Load($ll)
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
$field=$ctx.Web.Fields.GetByInternalNameOrTitle($SiteColumn)
foreach($cc in $ll.ContentTypes)
{
$link=new-object Microsoft.SharePoint.Client.FieldLinkCreationInformation
$link.Field=$field
$cc.FieldLinks.Add($link)
$cc.Update($false)
$ctx.ExecuteQuery()
}
$ctx.Dispose()
}
The script has been packaged and is available for download at the Technet Gallery. Click here to start download.
Create Site Column and Add to Content Type
The Item Content Type modified in the previous example has very limited reach. Our modifications affected only this list. What if we have a central content type created at a Content Type Hub level and would like to expand it and its children by one extra column?
*Site columns only get pushed out when they are attached to a content type. Which means that you can create the column on the hub but it will not get exported until it is attached to a content type which is published.
Create a Column
One of the options for adding a field is adding that field as an xml. The string below specifies the name and other properties of the column. If the Group is not specified,
the Column is added to Custom Columns group. If the specified Group does not exist yet, it will be created. "Show" properties define whether the column should appear in the forms while we are viewing, editing or creating an item. Name has to be unique.
** Remember! **
Contradictory column settings such as
Hidden="TRUE" and ShowinDisplayForm="TRUE"
will be ignored in the User Interface
$fieldXMLString = '<Field Type="DateTime"
Name="Predicted Date"
Description="Hokus pokus date"
DisplayName="Predicted Date I finish the Article"
StaticName="PredDateStaticName"
Group="Group I am Setting Now"
Hidden="FALSE"
Required="FALSE"
Sealed="FALSE"
ShowInDisplayForm="FALSE"
ShowInEditForm="TRUE"
ShowInListSettings="TRUE"
ShowInNewForm="TRUE"></Field>'
Some, but not all, of those properties can be set and modified via User Interface or SharePoint Designer:
$fieldSchema = '<Field Type="DateTime"
Name="Predicted Date"
Description="Hokus pokus date"
DisplayName="Predicted Date I finish the Article"
StaticName="PredDateStaticName"
Group="Group I am Setting Now"
Hidden="FALSE"
Required="FALSE"
Sealed="FALSE"
ShowInDisplayForm="FALSE"
ShowInEditForm="TRUE"
ShowInListSettings="TRUE"
ShowInNewForm="TRUE"></Field>'
$ctx.Web.Fields.AddFieldAsXml($FieldSchema,$true,[Microsoft.SharePoint.Client.AddFieldOptions]::AddFieldToDefaultView)
$ctx.Load($ctx.Web)
$ctx.ExecuteQuery()
The Column appears under Site Columns in the specified Group. In the browser url you can see the value of the Name property.
Create the Content Type
If you have a content type already created, you can skip this step. If you would like to find out more options on creating Content Types, please refer to SharePoint Online content types in Powershell: Add
$lci =New-Object Microsoft.SharePoint.Client.ContentTypeCreationInformation
$lci.Description="Some Custom Content Type"
$lci.Name="MyCustom"
$lci.Group="Prediction Content Types"
$contentType=$ctx.Web.ContentTypes.Add($lci)
$ctx.ExecuteQuery()
The Content Type appears immediately in the User Interface. The group to which it belongs did not exist before and was created at the creation of the content type. Because neither the parent content type, nor ID have been specified, the content type inherits from Item Content Type.
Add the Columns
In my newly created content two columns will be added: one pre-defined default "Anniversary" and the other newly created custom "Predicted Date". All child content types should be updated as well, so .Update() includes $true parameter.
#Modify the content type to add the columns
# newly created column
$link=new-object Microsoft.SharePoint.Client.FieldLinkCreationInformation
$link.Field=$ctx.Web.Fields.GetByInternalNameOrTitle("Predicted Date")
# one of pre-defined default columns
$link2=new-object Microsoft.SharePoint.Client.FieldLinkCreationInformation
$link2.Field=$ctx.Web.Fields.GetByInternalNameOrTitle("Anniversary")
$contentType.FieldLinks.Add($link)
$contentType.FieldLinks.Add($link2)
$contentType.Update($true)
$ctx.ExecuteQuery()
Full script
The full script has been packaged and is available for download at Technet Gallery. Click here to start direct download
Modify a Single Column in a Content Type
create a hidden column and add it to all content types called TASK
$fieldSchema = '<Field Type="DateTime"
Name="Petek"
Description="Piatek Piateczek Piatunio"
DisplayName="Petek"
StaticName="PredDateStaticName"
Group="Days of the Week Group"
Hidden="TRUE"></Field>'
The column does not appear neither in List Settings, nor under Content Types columns. It can be retrieved via Powershell
or accessed via direct url by entering the IDs for the content type,** list** where it is added and the field:
create a column to appear only after the item has been created
The user is creating an item with 2 required fields "Task Name" and "Friday". The Friday field is invisible for the creator of the item and hence not required at the creation:
The field, however, will appear and be required when we try to modify the same item:
How to achieve this?
Set the "appear in forms" setting:
$fieldSchema =** **'<Field Type="DateTime"
Name="Piatek"
Description="Piatek Piateczek Piatunio"
DisplayName="Friday"
StaticName="PredDateStaticName"
Group="Days of the Week Group"
Hidden="FALSE"
Required="TRUE"
Sealed="FALSE"
ShowInDisplayForm="TRUE"
ShowInEditForm="TRUE"
ShowInListSettings="FALSE"
ShowInNewForm="FALSE"></Field>'
Full scripts
The scripts above have been packaged and are available for download from Technet Gallery:
----fdsf-sd-f
------sdfsdfdsf---
Group
Gets or sets a value that specifies the content type group for the content type. The groups are visible in the User Interface in several places. Among others, they appear under Site Settings>Site Content Types:
To organize your Content Types, you can use default or Custom Groups.
If the group is not specified at the content type creation, the content type will be added to Custom Content Types by default.[4]
The group can be changed for all content types (some need to be unsealed, or changed from read-only first):
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$ctx.Load($ctx.Web.ContentTypes)
$ctx.ExecuteQuery()
foreach($cc in $ctx.Web.ContentTypes)
{
$cc.Group="Haha I invented one and it has them all"
$cc.Update($false)
$ctx.ExecuteQuery()
}
The default groups are available in the Technet Wiki article: SharePoint Online content types in Powershell: Group property .
A script for resetting the groups back to default is available at the Technet Gallery.
ID
The ID of a content type has a format similar to **0x01009e862727eed04408b2599b25356e7914 **and is not a modifiable property after the content type has been created. For more information on the meaning of the content type ID and setting this property while CREATING the content type, please refer to SharePoint Online content types in Powershell: Add - Content Type ID .
JSLink
Sets the custom template of the content type's display form. How to use JSlink and modify the view is described very well by Chris O'Brien and Martin Hatch in their respective articles Using JSLink to change the UI of a SharePoint list/view and ***JSLink and Display Templates. ***
$cc.JSLink="~site/SiteAssets/Accordion.js|~site/SiteAssets/jquery-ui-1.9.2.custom.js|~site/SiteAssets/jquery.ui.accordion.min.js"
$cc.Update($false)
$ctx.ExecuteQuery()
Name
Needs to be unique. Otherwise you will receive an error
Exception calling "ExecuteQuery" with "0" argument(s): "A duplicate content type name "All the same" was found."
$cc.Name="All the same"
$cc.Update($false)
$ctx.ExecuteQuery()
NameResource
Similarly to the DescriptionResource, the NameResource property does not seem to be one of the default content type's properties:
'NameResource' is not a member of type 'Microsoft.SharePoint.Client.ContentType'
Parent
Parent cannot be changed after the content type has been created. It seems logical as it would involve changing some of the content type default properties.
SchemaXML
SchemaXML is a string representation of the content type settings. It can be used to read and copy the content type, but as well cannot be changed using
$cc.SchemaXML=""
Scope
Returns a String. instance representing a server-relative path to the content type scope of the content type.
$ctx.Load($ctx.Web.Lists)
$ctx.ExecuteQuery()
foreach($ll in $ctx.Web.Lists)
{
$ctx.Load($ll.ContentTypes)
$ctx.ExecuteQuery()
foreach ($cc in $ll.ContentTypes)
{
Write-Host $ll.Title -ForegroundColor Green
Write-Host $cc.Name $cc.Scope
}
}
WorkflowAssociations
WorkflowAssociations property is a collection of all workflows associated with a particular content type. The workflows can be added, removed or edited from User Interface under Site Settings>>Site Content Types>>Choose the Content Type>> Workflow Settings or List Settings>>Content Types (Choose Content Type>> Workflow Settings:
Once you add the content type to a particular list, another option appears on the drop-down menu and you can choose the workflow from List Settings>>Workflow Settings:
$ctx.Load($cc.WorkflowAssociations)
$ctx.ExecuteQuery()
Write-Host $ll.Title -ForegroundColor Green
Write-Host $cc.Name $cc.WorkflowAssociations.Count
foreach($wf in $cc.WorkflowAssociations)
{
Write-Output $wf
}
Known errors
As this article has exceeded any expectations, for the sake of clarity, the Known Errors section has been moved to a new article.
Please find them under
SharePoint Online content types in Powershell: Known Errors
References
Articles
This article has spanned and is integrally connected with several other articles. For more information please look at:
SharePoint Online content types in Powershell: Add
SharePoint Online content types in Powershell: Get
SharePoint Online content types in Powershell: Group property
SharePoint Online content types in Powershell: Fields vs Field Links
SharePoint Online content types in Powershell: Known Errors
Downloads
Several (better or worse) scripts originated from this article. Most of them are available for download from Technet Gallery and are waiting for your comments there.
* Adding*
SharePoint Online: Create a content type using Powershell
Create content type and add directly to SPO list using Powershell
Create and add content type to a content type hub SharePoint Online
Create content type and add it to all lists in one site
Add Content Type to Task Lists
Add Content Type to Lists with Workflows
Add existing content type directly to SPO list using Powershell
*Getting *
Get all properties of all content types in a SharePoint site
Get All Properties of All Content Types (Detailed)
Get All Properties of All Content Types in All Lists (Detailed) across one site
Get properties of a single content type by its ID
Get content types belonging to a group
Get All Hidden Content Types added to the site
Get Single Content Type - Array Method
Get Names of all content types added to your SPO lists
Get Names of All Content Types
Get Names of all Available Content Types
Get Content Types Derived From One Parent
Get content types which cannot be modified
Get Content Types with a particular column
Find Custom Display Forms Deployed on your lists using Powershell
Verify the content types used in your lists against the default ones
Retrieve all Content Types from a Content Type Hub and their DisplayFormTemplate
Editing
"Unseal" sealed content types in SharePoint Online site collection
Modify the description of a list content type using Powershell
Modify the description of a site content type using Powershell
Unable to view items: modify the DisplayFormUrl back to default one
Modify the Display Form Template Name
Reset default content types
Add column (fieldlink) to a content type using Powershell
Assign your Content Types back to their default Groups using Powershell
Content Type Management
Allow content type management for all lists in site collection using Powershell
Allow content type management for all lists in a site using Powershell
Set content type management setting for SharePoint Online list using Powershell
Custom Powershell cmdlet Set-SPOList -ContentTypesEnabled
Related Scripts
SharePoint Online: Check content types added to your lists
SharePoint Online: Check content types added to your lists (recursive)
Get a report on lists where a given content type is added
SharePoint Online: Remove a content type from all lists in a site collection
Compare Web.AvailableContentTypes vs Web.ContentTypes
Fine Print
The statements provided here where the source is not quoted come from tests of the default behaviour. The tests were conducted on three different tenants 2 weeks apart and behaviour proved consistent which led to the conclusion that it is by design. However, in case of the DisplayFormTemplateName, on occassion, setting the incorrect name or different one did not bring the change in the behaviour visible in UI. So even though the DisplayFormTemplateName of an item was set to "MadeUp", the item would open correctly. As said the above-mentioned behaviour occurred only on occassion and was in clear minority, so in the chapter on DisplayFormTemplateName the dominating behaviour was described.
https://c.statcounter.com/10532038/0/eef75bd2/1/