Renaming an In-Use Content Type in SharePoint Online

Design of SharePoint content Types for SharePoint, and in particular SharePoint Online is very important. Care must be taken to ensure that the design is appropriate for the environment as changes made later can impose significant management overheads. In particular, if a Content Type is put to use (I.e. is assigned to a list/library), this can complicate changes made at a point following initial deployment.

Some Content Type operations are simple, e.g. adding a column. This will work as expected, with the new column rippling all the way down to the in-use Content Types.

Renaming a Content Type potentially falls under the ‘more difficult’ category, in particular if it’s been assigned to a list/library. This is due to the way that SharePoint handles this process, with the Content Type that is assigned to the list/library being a child content type of that published to a site collection.

I’d still strongly recommend using the Content Type Hub (hidden site collection, available on /sites/contenttypehub) to centrally manage and publish content types. A change to the name of a content type made here, then the content type being republished will rename the content type in the content type gallery in each site collection. If the content type is attached to a list/library however as this is a child content type, this will not be renamed, so you end up in the scenario that the gallery reflects the name change, while the instance attached to the list/library does not.

Looking at the list of content types attached to a list/library, and clicking through on the content type that you wish to change does allow you to change the content type from read-only to writeable. This then allows you to change the content type’s name, however if you have lots of libraries and/or lots of content types to process, this gets laborious very quickly. PowerShell to the rescue again!

The following script is a sample that can be used to change the name of a content type that is attached to a set of lists/libraries:

 1\[sourcecode language='powershell'  padlinenumbers='true'\]
 2$SiteUrl = ""  
 3$UserName = ""  
 4# Ask the user for the password
 5$Password = Read-Host -Prompt "Enter your password: " -AsSecureString
 7# List of lists/libraries to process
 8$libraries = @("Library1","Library2","Library3")
10# Add references to the CSOM libraries
11Add-Type -Path "C:\\<Path-to-CSOM-libraries>\\Microsoft.SharePoint.Client.dll" 
12Add-Type -Path "C:\\<Path-to-CSOM-libraries>\\Microsoft.SharePoint.Client.Runtime.dll" 
14# Connect
15$spoCtx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)  
16$spoCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $Password)   
17$spoCtx.Credentials = $spoCredentials
19# Load the web context
20$web = $spoCtx.web
24# Process the lists/libraries
25foreach ($lib in $libraries) {
26    $list = $web.lists.getbytitle("$lib")
27    $spoCtx.load($list)
28    $spoCtx.executeQuery()
30    # Load the content types attached to the list/library
31    $CTs = $list.ContentTypes
32    $spoCtx.load($CTs)
33    $spoCtx.executeQuery()
35    $IDToUse = ""
37    Write-Host "Processing library $lib" -ForegroundColor Yellow
38    foreach ($CT in $CTs) 
39    { 
40        Write-Host "-- " $CT.Name $Ct.Id
41        if ($CT.Name -eq "Content Type To Change")
42        {
43            $IDToUse = $CT.Id
44            Write-Host "Using this one..." -ForegroundColor Green
45        }
46    }
48    # Grab a reference to the content type we want to change
49    $CT = $list.ContentTypes.getbyid($IDToUse)
50    $spoCtx.load($CT)
51    $spoCtx.executeQuery()
53    if ($CT -ne $null)
54    {
55        # Set the content type to be writeable to be able to update it
56        Write-Host "Setting content type to ReadOnly = false" -ForegroundColor Green
57        $CT.ReadOnly = $false
58        $CT.Update($false)
59        $spoCtx.load($CT)
60        $spoCtx.executeQuery()
62        # Modify the content type name
63        Write-Host "Processing Content type..." -ForegroundColor Cyan
64        $CT.Name = "Content Type That Has Been Changed"
65        $CT.Update($false)
66        $spoCtx.load($CT)
67        $spoCtx.executeQuery()
69        # Return the content type to read-only
70        Write-Host "Setting content type to ReadOnly = true" -ForegroundColor Green
71        $CT.ReadOnly = $true
72        $CT.Update($false)
73        $spoCtx.load($CT)
74        $spoCtx.executeQuery()
75    }