Wednesday, 27 October 2010

Can’t remove a site column from a content type or list in SharePoint? Use PowerShell

There are particular site columns in SharePoint, which once added to a site content type or list cannot be removed again using the browser UI. An example of one of these columns in SharePoint Server 2010 is “Aliases”. If I add it to a content type and then click on the column name to remove it, you can see that the Remove button is not available.

image

This can cause much frustration and may even prompt you to completely delete the content type and start again – something that is usually impossible to do on a live environment.

Fortunately, we have PowerShell available to us for solving such problems. The script below will attach to the site containing your content type (also works for content type hubs), the content type itself, and then the link to the column within the content type. It then only takes a couple of lines to remove the column and update the content type.

The example below will remove the “Aliases” site column from the “Sales Document” site content type in http://portal:

#Attach to the web and content type
$web = Get-SPWeb
http://portal
$ct = $web.ContentTypes["Sales Document"]

#Get link to the columnn from the web
$spFieldLink = New-Object Microsoft.SharePoint.SPFieldLink ($web.Fields["Aliases"])

#Remove the column from the content type and update
$ct.FieldLinks.Delete($spFieldLink.Id)
$ct.Update()

#Dispose of the web object
$web.Dispose()

Phew!

Note that any columns of this type deleted from a parent content type will not automatically disappear in the child content types below it. The easiest way to get around this is to use the same script above to remove the site column from child content types, too.

Unfortunately, you may also find that if the content types containing this site column were attached to lists, then the lists themselves will also have the column added to them – even after removing the column from all associated content types. If this is the case, you will not be able to remove the column in the list using the browser UI as the Remove button will be missing on the column administration page here also.

To resolve this, you can either decide to remove the column using PowerShell one list at a time, or if there is a way of defining a batch of lists, use a script to modify multiple lists in one go. The script below provides you with an example of how to walk through each document library of a specified name on each site of the site collection and delete the offending column. If you do decide to run a script like this, please ensure you have fully tested it in a development environment beforehand due to the potential damage that it could inflict:

#Delete column on a specified list in all sites of a site collection
$site = Get-SPSite http://portal
$site | Get-SPWeb -Limit all | ForEach-Object {
    #Specify list which contains the column
    $list = $_.Lists["Pages"]
    #Specify column to be deleted
    $field = $list.Fields["Aliases"]
    #Allow column to be deleted
    $field.AllowDeletion = $true
    #Delete the column
    $field.Delete()
    #Update the list
    $list.Update()
}
$site.Dispose()

22 comments:

  1. When I try to run "$spFieldLink = New-Object Microsoft.SharePoint.SPFieldLink ($web.Fields["Aliases"])" in PowerShell, I get the following error: Constructor not found. Cannot find an appropriate constructor for type Microsoft.Sharepoint.SPFieldLink.

    Any idea on why I am gettting this error? I have the SharePoint snapin installed.

    Thanks

    ReplyDelete
    Replies
    1. This modified script works for those columns that are not visible/editable.

      #Attach to the web and content type
      $web = Get-SPWeb http://portal
      $ct = $web.ContentTypes["Sales Document"]

      #Get the fieldLink (optional check for existence)
      $ct.FieldLinks["myColumn"]

      #delete the fieldLink
      $ct.FieldLinks.Delete("myColumn")
      $ct.Update($true)

      #true here, as stated in one of the last comments, will push changes to children.
      #Dispose of the web object
      $web.Dispose()

      Delete
    2. Thanks, this worked for the Active ("RoutingEnabled")column

      Delete
  2. Hi - try removing the space between SPFieldLink and ($web.Fields... for example:

    $spFieldLink = New-Object Microsoft.SharePoint.SPFieldLink($web.Fields["Aliases"])

    It could be a syntax error with my script.

    ReplyDelete
  3. Tried it with and without the space and it works for me, so not sure...

    ReplyDelete
  4. I ran into the same issue. Some columns imported, others did not. In looking through the XML output, I noticed that the columns that did not import either were from a Feature that needed to be activated or were from a Custom Site Column. Check out Phil Childs's post on "Export and import/create site columns in SharePoint using PowerShell" to fix the issue. (http://get-spscripts.com/2011/01/export-and-importcreate-site-columns-in.html)

    ReplyDelete
  5. I have a site that has a large number of subsites and libraries under it. I am trying to remove a content type from the site collection, but there are 6740 libraries(yes, really) that have the content type assigned to them.

    Is there a way to remove the content type on a mass scale from the libraries via Powershell for WSS/2007?

    ReplyDelete
  6. Josh - I have a couple of articles on removing content types from documents (http://get-spscripts.com/2010/10/change-content-type-set-on-files-in.html) and then lists (http://get-spscripts.com/2010/11/add-and-remove-site-content-types-from.html) which you would have to do before removing it from the site collection. You shoukd be able to convert the scripts to work with SP 2007 by looking at this article: http://get-spscripts.com/2011/03/using-powershell-scripts-with-wss-30.html.

    Good luck!

    ReplyDelete
  7. in your first script block, i believe adding $true to the update method will push the changes (deletion) to all the child content types:

    $ct.Update($true)

    ReplyDelete
  8. Saved me :-) Thanks Phil

    ReplyDelete
  9. I am very new to PowerShell and can't get this command to work with SharePoint 2007, would any kind soul out there have a version that they have used successfully in 2007 that they'd like to pass on? Many thanks in advance.
    Paul

    ReplyDelete
    Replies
    1. Anonymous - PowerShell is only available in SharePoint 2010+
      I am not aware of a STSADM command that does the same...

      Delete
  10. Just thought I'd let you know that further to my query above I managed to fix this problem by using "SharePoint Manager 2007" from Codeplex. This tool allows you to navigate down to a field and change the AllowDeletion property to True. Then when you go to the column properties the Remove button is available and you can delete in the usual way.
    Paul

    ReplyDelete
  11. I've eights site columns under group "E-mail Submission Columns". Each columns shows up three times in the list. The site column is not in use under any content type. Email Submission CT was removed.

    I don't see delete option for these 8 site columns! How can I use your script to accomplish that?

    Thanks
    Frank

    ReplyDelete
  12. Thanks Phil.this saved my day.I was struggling to remove the site columns from the doc.lib references and its associated content types. You code helped me to fix that and worked like a charm.You are doing a great job helping the SP developers like me and making our life easier!
    Thanks Again!

    ReplyDelete
  13. Today, we get a first look at the adidas Tubular Invader 2.0 that will be debuting as part of adidas Originals’ Fall/Winter 2016 Collection.The adidas Tubular Invader 2.0 is a street-ready silhouette that yeezy boost 350 has a sporty style. This 2.0 version of the Tubular Invader is a strap-free model that features full grain leather yeezy shoes uppers with dramatic cut on the collar and snakeskin embossed heel panels. Completing the look is a soft EVA midsole adidas nmd R1 and rubber outsole.Check out these two upcoming colorways in “White” and “Black” below and look for either of them available Yeezy Boost 350 Turtle Dove today through select adidas Originals retail stores, including shops like like The Good Will Out.
    The adidas Ultra Boost “Triple Adidas Yeezy Black” is expected to take the popularity of the adidas Ultra Boost silhouette to the next level.Reason being, it’s the adidas nmd first release to feature an all-Black Boost cushioning sole on the adidas Ultra Boost silhouette. Matching the Boost sole is NMD Human Race Yellow an entire all-Black upper that includes matching Blackout laces, heel counter, and cage overlay.Look for the adidas Ultra Boost “Triple Adidas Shoes Black” to release this holiday season at select adidas Originals retail stores. The retail price tag is set at $180 Adidas Basketball Shoes USD.
    For Fall 2016, adidas Originals will be introducing their latest adidas NMD XR1 Camo Pack that consists of two adidas stan smith adidas NMD XR1 colorways.Dressed in either Black or White, both adidas NMD releases features a camouflage graphic atop a mesh adidas shoes constructed upper. The “White Camo” pair features a Black heel tab and matching Black rubber outsole. While the “Black Camo” Yeezy Boost 350 edition sports a White heel tab and White rubber outsole. They’re both completed with a full-length White Boost midsole.Check out Adidas Ultra Boost

    ReplyDelete