PNP PowerShell: Managing Content Type Artefacts across a single or multiple Office 365 tenants

Creating content types in Sharepoint has always been relatively easy for site and content administrators. Furthermore, with the Content Type Hub feature, custom content types can be centrally defined and pushed out to all site collections. The challenges and difficulties, however arise when you want to make some inherent changes to these site objects or want these exact site objects to be present across your DTAP (Dev, Test, Acceptance & Production

For instance,

  • I’ve created my custom content types in my dev tenant. Now I want to migrate the changes to production?
  • How can I update an internal name of a field with a content type and ensure that the changes are reflected everywhere?

Actions like these were (and still are) generally avoided because there’s be no good way of accomplishing them. It’s still very good practice to thoroughly prepare and review what’s needed before creating custom content types. Making changes to these artefacts still requires effort especially when there is content that is already using these artefacts.

Fortunately, the ability to manage existing content types has gotten easier. Thanks to the efforts in the Microsoft Patterns & Practices (PnP) community.

We now have a set of useful PowerShell cmdlets that can help us. The list of cmdlets is continuously growing and we find that as administrators we can accomplish many more tasks using CSOM

You can go through the PnP Cmdlet documentation here https://github.com/SharePoint/PnP-PowerShell/tree/master/Documentation

I want to focus on creating content types and managing changes to these artefacts you use the following 2 PNP cmdlets

Get-PnPProvisioningTemplate: Enables you to extract a site template with all or a partial set of the site artifacts. The extraction is an xml file which can be reviewed and updated

Apply-PnPProvisionTemplate: Enables you to apply an extracted site template to an existing site. Essentially providing you with a means to apply changes how to all sites in a tenant or a different tenant

The overall process then would look like this:

Create custom artefacts in content type hub

As usual create your fields and content types in the content type hub. I recommend to:

  • Tag these artefacts in a custom group so they are easily identifiable
  • Decide on a naming convention for both fields and content types that helps others to see that these are custom artefacts
  • Avoid spaces in field names when initially creating them. Otherwise you end up with internal names looking like this

Where the space is replaced with a hexadecimal “_x0020_”. This is not a critical issue, however can be avoided and corrected.

I’ve created a content type in a unique group:

With a custom field Document Category

Extract artefacts using Get-PnPProvisioningTemplate:

Using the cmdlet, I can first enter credentials connect to my SPO tenant content type hub site collection

Then extract only the Fields and Content Types using the -Handler attribute

Make changes to your artefacts in XML

In your xml output file, you will find all the Fields and Content Types. You search for the relevant ones by looking for the group name (“Demo Only” in my case)

You can now edit field properties such as the StaticName and Name

Be sure to update the reference to the update field name in the corresponding content types as well. In my case I had created a “Demo Content type”

Modified to

Once your satisfied with you changes save the XML file and you are ready to apply the changes to the original content type hub site collection

Apply changes using

Connect to your content type hub site collection again:

Run the Apply-PnPProvisioningTemplate with the updated xml file as an input:

I changed the static name of “Document_x0020_Category” to “Document_Category” which is not reflected in when viewing the field column URL:

This was a simple demonstration of the scripting tools available to manage site artefacts change that previously were difficult or impossible to update.

Changes can now be pushed out to all site collections by republishing the updated content type:

Using this same technique, with a bit more preparation you can also extract a set of custom content types for one tenant and apply them to another. Thereby keeping field names, content types and their internal GUIDs all intact!