Thumbnail Moving existing Content Types to the Content Type Hub

Moving existing Content Types to the Content Type Hub

If we could start afresh, we would all do things differently, wouldn’t we? I often muse on the possibilities of starting with a clean slate. But when designing a new information architecture for a customer, we often need to accept that there’s an existing architecture that we cannot just drop. Or not without serious consequences. We often need to take that architecture as a starting point.

Todays post is on dealing with existing Content Types and the desire to move to the Content Type Hub! A prime example of having to deal with an existing architecture.

Picture a SharePoint tenant where a previous IT-supplier has created a number of Content Types for Documents. These Content Types extend the default ‘Document’ Content Type and have a series of additional columns. These content types have been used in a number of sites and have been integrated into new sites using a provisioning solution. It may be nice work. It may be really structured, and it may be used extensively by the users.

But every time an additional column is needed, it needs to be added to all those Content Types across all those sites. Someone is commissioned to execute a PowerShell script which the IT-supplier left behind. This script creates the site column in all existing sites and adds them to the Content Types. The one executing this script will need to monitor it for errors and may have some manual work to get things neat and tidy. Someone will also need to update the provisioning solution to include the new column.

For such a scenario it would have been nice if the “Content Type Hub” had been used instead. The Content Type Hub is a central place where you can manage Content Types for your entire tenant. It’s a specific type of site collection, which can be found at the URL https://contoso.sharepoint.com/sites/contenttypehub. But it’s also integrated into the SharePoint Admin portal and you can manage your Content Types (and columns) from there and have them available in a set of “subscribed” site collections: sites where these content types have been added. They will be kept up-to-date by an automated SharePoint job/process.

It’s a great way to ensure consistency in your Content Types and Metadata without all the scripting and manual work mentioned above. It’s an easy place to give certain super users the permissions to manage central Content Types and Metadata, which Microsoft will then sync across the subscribed sites.

So is it possible to move from the scenario described above to a scenario where the Content Type Hub is used? Well… it depends. There’s all these old sites to consider.

  1. We could decide to keep the old sites as they are and only use the Content Type Hub for new sites. But that would mean we’d still have to manage Content Types in multiple places, still partially using scripting and manual work.

  2. We could also migrate all these old sites to new sites that are based on the new approach. But that’s a lot of work and may not be feasible.

Both options are not ideal. So is there a better way?

Well, it depends on the Content Type Id’s that are in use.

There is a third option, but it will only work if Content Types have been created across sites with fixed Content Type Id’s. I’ll explain in a moment why that is important.

As you may know, Content Types have a very specific Id structure, an in depth description of which can be found here. If we create a new Content Type inheriting from the default Document Content Type, it will get a new Id, in which the inheritance is clearly traceable. For example: 0x010100dfc36c3302014718b129edd3897f190f.

The following image shows how that Id can be broken down:

Content Type Id Structure

It’s basically just the Id of the parent in the inheritance chain, combined with 00 and a new GUID without dashes. Adding such a content type to a library will add an additional 00 and an additional GUID without dashes, so you can distinguish the List Content Type from the Site Content Type:

(Site Content Type Id)
0x010100dfc36c3302014718b129edd3897f190f
(List Content Type Id)
0x010100dfc36c3302014718b129edd3897f190f00cb713b9dbe7f4e2a901df21f6d019f83

Now if we create a new Content Type using the User Interface of SharePoint, the new Id’s will always have random GUID’s in them. But it’s also possible to create a Content Type programmatically, using PowerShell for example, and give it a fixed Id. Of course, we’d need to make sure that the Id is correct, according to the rules.

The following PnP PowerShell script creates a new Content Type with a fixed Id:

Add-PnPContentType -ContentTypeId "0x010100dfc36c3302014718b129edd3897f190f" -Name "Blimped Document" -Group "Contoso Content Types"

👏 Today we’re in luck, the provisioning solution mentioned in the scenario above created Content Types on all sites with fixed Id’s. So the ‘Blimped Document’ Content Type has the same Id on all sites.

So why does that matter?

The idea is that we can recreate that same Content Type in the Content Type Hub. We can create it using PowerShell and reuse the Id from that same content type on the existing sites. Because the Id’s are the same, SharePoint will now recognize that it’s the same Content Type, and give us the opportunity to “Update” the Content Type on existing sites. This effectively subscribes the sites to the Content Type Hub and SharePoint will in the future now automatically update the Content Types in the sites… because the Id’s are the same.

I took the following screenshot on a random site after recreating my Content Type in the Content Type Hub. As you can see, SharePoint recognizes that the same Content Type is available from the Content Type Hub, and offers to update it:

After hitting the update button, the changes from the Content Type Hub are applied to the Content Type on the site. In this case it removed some columns and it added some new ones:

Note: If the Content Type Hub sync removes columns from a Content Type, these columns are left orphaned in libraries where they were used. Metadata is not lost, but the columns will no longer show in any form.

The above process can be done manually, like I did in the screenshots. But it can also be done using a script. The following PnP PowerShell script will subscribe a site to use the Content Type from the Content Type Hub. It would be very easy to loop through all sites in a tenant and subscribe them all to the Content Type sync from the Content Type Hub:

Add-PnPContentTypesFromContentTypeHub -ContentTypes "0x010100dfc36c3302014718b129edd3897f190f" -Site "https://contoso.sharepoint.com/sites/sales"

💪 The result will be that we can now manage the Content Types on existing sites from the Content Type Hub.

Note: If we recreate a Content Type in the Content Type Hub using the same Id as was used on existing sites, we can let these sites subscribe to the Content Type Sync process.

It’s not always possible to start from scratch. But when we have to deal with existing Content Types and we want to move to the Content Type Hub, it’s possible to do so. That is: if the Content Types have been created with fixed Id’s, we can recreate them in the Content Type Hub and let existing sites subscribe to the Content Type Sync process. This way we can manage Content Types from a central place and have them automatically updated in all sites.


sharepoint information-architecture
Support me by sharing this

More

More blogs

Extending Microsoft 365 with custom retention controls
Extending Microsoft 365 with custom retention controls

Thinking about a Purview post by Joanne C Klein, I've developed a small Microsoft 365 extension to view & manage retention controls.

Read more
Debugging production code in SPFx
Debugging production code in SPFx

A way to debug minified SPFx code in production against your original typescript code.

Read more
Resource Specific Consent - Using delegated Sites.Selected
Resource Specific Consent - Using delegated Sites.Selected

Sites.Selected has been made available in delegated mode! What does it mean and how does it work?

Read more

Thanks

Thanks for reading

Thanks for reading my blog, I hope you got what you came for. Blogs of others have been super important during my work. This site is me returning the favor. If you read anything you do not understand because I failed to clarify it enough, please drop me a post using my socials or the contact form.


Warm regards,
Martin

Microsoft MVP | Microsoft 365 Architect

Microsoft MVP horizontal