Add Content Types in SharePoint Online with CSOM


If you have created your portal in Office 365 and you started adding, you might find yourself at some point that you need to add a new content type and attach it to an existing library. This is typically pretty easy and straight forward if you are adding your new content type to few libraries, but definitely a big headache if you have hundreds or thousands of libraries that must have the new content type. Of course, you cannot delete the library and re-create it from a template, because you have already content in them, then your only option in this case is to script it.

If you are on-premises this is pretty easy, with few lines of PowerShell script, you will be able to achieve what you are looking for. PowerShell on-premises code will look like this:

$site = "http://sp2013/sites/Depts"
$site = Get-SPSite $siteURL
$webRoot = $site.RootWeb
$site | Get-SPWeb -limit all | ForEach-Object{
 $web=Get-SPWeb $_.Url
        $customCT = "HR Document"
        $Lib = $web.Lists[“Pages”]
        #make sure you enable content types
 $Lib.ContentTypesEnabled = $true
        $ContentType = $webRoot.ContentTypes[$customCT]

The above code will not work in SharePoint Online, so we will have to develop CSOM Code to be able to manage the content types remotely. Here is what you need to run:

First, you need to add references to your SharePoint client assemblies.

Add-Type -Path (Resolve-Path "C:\CreatePublishingSite\Microsoft.SharePoint.Client.dll")
Add-Type -Path (Resolve-Path "C:\CreatePublishingSite\Microsoft.SharePoint.Client.Runtime.dll")
Add-Type -Path (Resolve-Path "C:\CreatePublishingSite\Microsoft.SharePoint.Client.Publishing.dll")

Second, you need to authenticate to your SharePoint Online tenant and load your XML file:

$userName = "[email protected]"
$pwd = Read-Host -AsSecureString "Please enter your password"

Third, load the site collection and get the Content Type to apply it to a specific web

$webUrl= ""
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($webUrl)
$siteContext = $clientContext.Site
$RoootWebContext = $siteContext.RootWeb
$webContext = New-Object Microsoft.SharePoint.Client.ClientContext($webUrl)

foreach($currentWeb in $webUrl.Webs.Web) {
$currentWeb = $RoootWebContext.Webs.Context.Web
#Get Content Type By Id
$ct = $RoootWebContext.ContentTypes.GetById("0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D400BE6DDBAE4894D74D967E5A1A188C147C")
$list = $currentWeb.Lists.GetByTitle("Pages")
$cts = $list.ContentTypes
$ctReturn = $cts.AddExistingContentType($ct)