Removing duplicate fields in a SP Content Type with PowerShell

Published on 31 July 2018 by Vincent. Reading time: 2 minutes.

Introduction

When building new possibilities for a customer that uses SharePoint, we always need to update the existing infrastructure that is already available with a PowerShell scripts.

Problem

After running one of those scripts we found a small problem, when creating documents in a specific SharePoint document library the following screen was presented.

 

Removing duplicate fields in a SP content type with Powershell

Figure 1: Two fields are double when adding a document

 

As you might notice two fields are returned twice. These fields weren’t listed twice in the library fields, so where do they come from?

After some further search we found the troublemaker, it was a Content Types that was connected to the list. In here the fields where listed twice.

 

Solution

Now we know what the problem is, we can create a new PowerShell to correct this problem.

if(-not (Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction:SilentlyContinue)){ Add-PSSnapin Microsoft.SharePoint.PowerShell }

$url  = "https://{Your Root SP Url}/*"

function Process() {
    $sites = Get-SPSite  $url -Limit ALL

    write-host "Removing duplicate field in CT for $url"

    foreach($site in $sites)
    {
        $web = $site.RootWeb
        ProcessWeb -web $web -site $site

        foreach($subweb in $web.Webs)
        {
            if ($subweb){
                ProcessWeb -web $subweb -site $site
            }
        }
    }

    write-host "All done !" -ForegroundColor Green
}

function ProcessWeb($web, $site) {
    $lists = $web.Lists
    foreach($list in $lists)
    {
        ProcessList -list $list -web $web -site $site
    }
}

function ProcessList($list, $web, $site) {
    $listCts = $list.ContentTypes;
    foreach($listCt in $listCts)
    {
        ProcessListCt -ct $listCt -list $list -web $web -site $site
    }
}

function ProcessListCt($ct, $list, $web, $site) {
    $foundFields = @()
    $fields = $ct.Fields;
    foreach($field in $fields) {
        if($foundFields -contains $field.InternalName) {
            write-host "Duplicate field found" -ForegroundColor Red
            write-host "Site = $site, Web = $web, List = $list, CT = " $ct.Name ", Field = " $field.InternalName

            $ct.FieldLinks.Delete($field.Id)
            $ct.Update()
        } else {
            $foundFields += $field.InternalName
        }
    }
}

Process

 

In the script we loop through all the sites in your environment, into the webs, the lists and eventually in the content types of the list.

At this point the script loops through all the fields and checks if it is already contained in the created foundFields array. If not then the InternalName is added to the array and if the array contains the InternalName name of the field then that field will be deleted from the content type and the content type is updated.

Tags: SharePoint

Vincent

Published by Vincent on 31 July 2018

Senior Developer at ETTU since 2006. As developer my main focus is coding software like Sharepoint Add-ins and MVC websites that helps my customers in their daily work. Besides that I have 2 other interests that help me do the job; UX and Scrum. Thats why I am UX-certified with a web design specialty (@ Nielsen Norman Group) and a Professional Scrum Master (@ scrum.org)

 

Comments? Share them below

Learn more about ETTU

And the way we work