SharePoint Online: Find Content Type usage using PowerShell
Requirement: Find where a Content Type is being used in SharePoint Online.
Want to get the usage information for content types in SharePoint Online? Well, In this blog post, we will show you how to find out how content types are being used in SharePoint Online using PowerShell. You may have to find the content type usage in scenarios like:
- You are getting the “content type is still in use” error when trying to delete a content type.
- You are trying to determine where a particular content type is used, etc.
PowerShell to Find Content Type Usage in SharePoint Online
A content type describes the metadata and behavior of items in a list or library. Unlike SharePoint On-premises, We don’t have SPContentTypeUsage class available in CSOM. So, we are left with an option: Scan each and every list to get the content type usage!
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
#Function to get the content type usage
Function Find-SPOContentTypeUsage([String]$SiteURL)
{
Try{
Write-host -f Yellow "Processing Site:" $SiteURL
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
#Get All Lists of the Web
$Ctx.Load($Ctx.Web)
$Ctx.Load($Ctx.Web.Lists)
$Ctx.Load($ctx.Web.Webs)
$Ctx.ExecuteQuery()
#Get content types of each list from the web
$ContentTypeUsages=@()
ForEach($List in $Ctx.Web.Lists)
{
$ContentTypes = $List.ContentTypes
$Ctx.Load($ContentTypes)
$Ctx.Load($List.RootFolder)
$Ctx.ExecuteQuery()
#Get List URL
If($Ctx.Web.ServerRelativeUrl -ne "/")
{
$ListURL= $("{0}{1}" -f $Ctx.Web.Url.Replace($Ctx.Web.ServerRelativeUrl,''), $List.RootFolder.ServerRelativeUrl)
}
else
{
$ListURL= $("{0}{1}" -f $Ctx.Web.Url, $List.RootFolder.ServerRelativeUrl)
}
#Get each content type data
ForEach($CType in $ContentTypes)
{
$ContentTypeUsage = New-Object PSObject
$ContentTypeUsage | Add-Member NoteProperty SiteURL($SiteURL)
$ContentTypeUsage | Add-Member NoteProperty ListName($List.Title)
$ContentTypeUsage | Add-Member NoteProperty ListURL($ListURL)
$ContentTypeUsage | Add-Member NoteProperty ContentTypeName($CType.Name)
$ContentTypeUsages += $ContentTypeUsage
}
}
#Export the result to CSV file
$ContentTypeUsages | Export-CSV $ReportOutput -NoTypeInformation -Append
#Iterate through each subsite of the current web and call the function recursively
foreach ($Subweb in $Ctx.web.Webs)
{
#Call the function recursively to process all subsites underneaththe current web
Find-SPOContentTypeUsage($Subweb.url)
}
}
Catch {
write-host -f Red "Error Generating Content Type Usage Report!" $_.Exception.Message
}
}
#Config Parameters
$SiteURL="https://crescent.sharepoint.com"
$ReportOutput ="C:\Temp\ContentTypeUsage.csv"
#Get Credentials to connect
$Cred= Get-Credential
#Delete the Output Report, if exists
if (Test-Path $ReportOutput) { Remove-Item $ReportOutput }
#Call the function to get the content type usage
Find-SPOContentTypeUsage $SiteURL
Here is the sample output of the script.
This PowerShell script gets all content types of all lists and libraries in a SharePoint Online site collection. What if you want to find where a specific content type is used?
SharePoint Online: Find Where a Specific Content Type is used using PowerShell
Now, let’s find all documents with a content type in SharePoint Online using PowerShell. Here is how to get content type usage in SharePoint Online.
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
#Function to get a particular content type usage
Function Get-SPOContentTypeUsage([String]$SiteURL, [String]$ContentTypeName)
{
Try{
Write-host -f Yellow "Processing Site:" $SiteURL
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
#Get All Lists of the Web
$Ctx.Load($Ctx.Web)
$Ctx.Load($Ctx.Web.Lists)
$Ctx.Load($ctx.Web.Webs)
$Ctx.ExecuteQuery()
#Get content types of each list from the web
$ContentTypeUsages=@()
ForEach($List in $Ctx.Web.Lists)
{
$ContentTypes = $List.ContentTypes
$Ctx.Load($ContentTypes)
$Ctx.Load($List.RootFolder)
$Ctx.ExecuteQuery()
#Get List URL
If($Ctx.Web.ServerRelativeUrl -ne "/")
{
$ListURL= $("{0}{1}" -f $Ctx.Web.Url.Replace($Ctx.Web.ServerRelativeUrl,''), $List.RootFolder.ServerRelativeUrl)
}
else
{
$ListURL= $("{0}{1}" -f $Ctx.Web.Url, $List.RootFolder.ServerRelativeUrl)
}
#Get each content type data
ForEach($CType in $ContentTypes)
{
If($CType.Name -eq $ContentTypeName)
{
$ContentTypeUsage = New-Object PSObject
$ContentTypeUsage | Add-Member NoteProperty SiteURL($SiteURL)
$ContentTypeUsage | Add-Member NoteProperty ListName($List.Title)
$ContentTypeUsage | Add-Member NoteProperty ListURL($ListURL)
$ContentTypeUsage | Add-Member NoteProperty ContentTypeName($CType.Name)
$ContentTypeUsages += $ContentTypeUsage
Write-host -f Green "Found the Content Type at:" $ListURL
}
}
}
#Export the result to CSV file
$ContentTypeUsages | Export-CSV $ReportOutput -NoTypeInformation -Append
#Iterate through each subsite of the current web and call the function recursively
foreach ($Subweb in $Ctx.web.Webs)
{
#Call the function recursively to process all subsites underneaththe current web
Get-SPOContentTypeUsage $Subweb.url $ContentTypeName
}
}
Catch {
write-host -f Red "Error Generating Content Type Usage Report!" $_.Exception.Message
}
}
#Config Parameters
$SiteURL="https://crescent.sharepoint.com"
$ReportOutput ="C:\Temp\ContentTypeUsage.csv"
$ContentTypeName="Business Contacts"
#Get Credentials to connect
$Cred= Get-Credential
#Delete the Output Report, if exists
if (Test-Path $ReportOutput) { Remove-Item $ReportOutput }
#Call the function to get the content type usage
Get-SPOContentTypeUsage $SiteURL $ContentTypeName
This PowerShell finds files with content types in SharePoint Online, and it also gets you all locations of the specific content type usage.
PnP PowerShell to Get Content Type Usage in SharePoint Online Site
#Parameters
$SiteURL="https://crescent.sharepoint.com/sites/PMO"
$ReportOutput ="C:\Temp\ContentTypeUsage.csv"
$ContentTypeName="Crescent Project V2"
#Delete the Output Report, if exists
If (Test-Path $ReportOutput) { Remove-Item $ReportOutput }
Try{
#Connect to the Site
Connect-PnPOnline -Url $SiteURL -Interactive
#Get All Lists
$Lists = Get-PnPList -Includes RootFolder | Where-Object {$_.Hidden -eq $False}
#Get content types of each list from the web
$ContentTypeUsages=@()
ForEach($List in $Lists)
{
Write-host -f Yellow "Scanning List:" $List.Title
$ListURL = $List.RootFolder.ServerRelativeUrl
#get all content types from the list
$ContentType = Get-PnPContentType -List $List | Where {$_.Name -eq $ContentTypeName}
#Collect list details
If($ContentType)
{
$ContentTypeUsage = New-Object PSObject
$ContentTypeUsage | Add-Member NoteProperty SiteURL($SiteURL)
$ContentTypeUsage | Add-Member NoteProperty ListName($List.Title)
$ContentTypeUsage | Add-Member NoteProperty ListURL($ListURL)
$ContentTypeUsage | Add-Member NoteProperty ContentTypeName($ContentType.Name)
Write-host -f Green "`tFound the Content Type in Use!"
#Export the result to CSV file
$ContentTypeUsage | Export-CSV $ReportOutput -NoTypeInformation -Append
}
}
}
Catch {
write-host -f Red "Error Generating Content Type Usage Report!" $_.Exception.Message
}
Please note that you cannot delete a content type as long as the content type is in use on any SharePoint sites. Also, To remove a content type from the SharePoint site, any item that uses the particular content type must either change its content type or completely be removed (even from the 1st stage & 2nd stage recycle bins).
Here is another post to find where a content type is used in SharePoint On-premises: Find Content Type Usage in SharePoint using PowerShell
Hi Salaudeen,
Thank you for the response, not sure if I’ve misunderstood something though. The issue is with 2 content types in a site that is not itself a Hub site; but yet I can’t delete the two content types because SPO claims they are in use somewhere. It’s my understanding that content types can only be shared down (i.e. from Hub site to sub sites) but not up nor across?
I suspect this is one I need to take up with MS support (yay me)…
Hi Salaudeen,
I’m attempting to use your solutions, but I’m getting the following error at runtime,
Error Generating Content Type Usage Report! Exception calling “ExecuteQuery” with “0” argument(s): “The sign-in name or password does not match one in the Microsoft account system.”
I rather suspect it’s due to MFA, and I’m trying to fathom how I replace your connection method with:
connect-pnponline -url “target” -interactive
Any advise?
Sounds like your account is MFA enabled! PnP PowerShell supports MFA-enabled accounts natively. I’ve added the PnP script to the article.
Hi Salaudeen,
Thanks for that – I can confirm the script works having tested it in a site with type I know is in use, all I need to do now is figure out why a site with 2 content types which say they’re in use aren’t being reported as such in the script!
*muses* is it possible to run something recursively from the main path to search iteratively through all hub sub sites?
This should help: PowerShell to Get All Sites Associated with the Hub Sites in SharePoint Online