Programatically reassigning Content Types in a library

86

Reassigning Content Types in a library using PowerShell

It is useful to be able to change the Content Type for each document in a library to a new Content Type. Perhaps you are consolidating, or just moving to a new Content Type hierarchy. There are a few tricks to changing a Content Type for a document. First, you’ll need to force a check-in if a document is checked out. Next, you’ll want to reference the Content Type by ID, specifically using this method: $list.Items.GetItemById($item.ID). Any other attempt to reassign a Content Type will fail. Lastly, either do a systemupdate() or clean up after yourself by restoring the timestamp, editor, and delete interim versions. Note there needs to be sufficient metadata, or the change will result in an error and/or the document being left checked out. This function traps and reports this condition. Here’s the function we will use:

function Reset-SPFileContentType ($WebUrl, $ListName, $OldCTName, $NewCTName)
{
    #Get web, list and content type objects
    $web = Get-SPWeb $WebUrl
    $list = $web.Lists[$ListName]
    $oldCT = $list.ContentTypes[$OldCTName]
    $newCT = $list.ContentTypes[$NewCTName]
    $newCTID = $newCT.ID
    
    #Check if the values specified for the content types actually exist on the list
    if (($oldCT -ne $null) -and ($newCT -ne $null))
    {
        #Go through each item in the list
        $list.Items | ForEach-Object {
            #Check if the item content type currently equals the old content type specified
            if ($_.ContentType.Name -eq $oldCT.Name)
            {
			    $ForcedCheckin=$false;
                if ($_.File.CheckOutType -ne "None")
                {
                   try { 
                     $_.File.CheckIn(“Checked In By Administrator”);
                     
                     write-host -foregroup Yellow "Forced checkin for $($_.File.Title)"
                   }
                   catch { 
                     
                     write-host -foregroup Red "FAILED to Force checkin for $($_.File.Title)"
					 $ForcedCheckin=$false;
                   }
                }

                #Check the check out status of the file
                if ($_.File.CheckOutType -eq "None")
                {

                   $item=$_
                   [System.DateTime]$date = $item["Modified"]
                   $user = New-Object microsoft.SharePoint.SPFieldUserValue($web, $item["Editor"])

                   try { #untested try, failure could be due to inadequate required metadata
                    #Change the content type association for the item
      [Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges(
      {
        $item2 = $list.Items.GetItemById($item.ID);
#CHECKOUT NOT REALLY NEEDED, IF MUSTCHECKOUT IS DISABLED EARLIER
#        $item2.File.CheckOut()

#write-host $item2['Name']
Write-Host "." -NoNewline

        
        $item2["ContentTypeId"] = $newCTID
        $item2.Update()

        $item2["Modified"] = $date;
        $item2["Editor"] = $user;
        $item2.Update()

        #get rid of the last two versions now, trapping any errors 
        try { $item2.Versions[1].delete() } catch {write-host -foregroundcolor red "Error (1) could not delete old version of $($item2['Name'])"}
        try { $item2.Versions[1].delete() } catch {write-host -foregroundcolor red "Error (2) could not delete old version of $($item2['Name'])"}
		if ($ForcedCheckin)
		{try { $item2.Versions[1].delete() } catch {write-host -foregroundcolor red "Error (3) could not delete ForcedCheckin version of $($item2['Name'])"}}

#get rid of the last version now

#        $item2.File.CheckIn("Content type changed to " + $newCT.Name, 1)
     } )

    } catch { write-host -foregroundcolor red "Error (possibly inadequate metadata) updating file: $($_.Name) from $oldCT.Name to $($newCT.Name)"
              
             }

            }
                else
                {
                    write-host -foregroundcolor red "File $($_.Name) is checked out to $($_.File.CheckedOutByUser.ToString()) and cannot be modified";
                   
                }
            }
            else
            {
                 #Write-Host -ForegroundColor DarkRed "File $($_.Name) is associated with the content type $($_.ContentType.Name) and shall not be modified `n";
            }
        }
    }
    else
    {
        write-host -foregroundcolor red "One of the content types specified has not been attached to the list $($list.Title)"
        
    }

  $web.Dispose()
}

Next, let’s just call the function passing in the old name and the new name:

reset-spfilecontenttype -weburl $weburl -listname $JPlib  -oldctname "Documents" -newctname "DOCS"

Share this entry

Leave a Reply

Your email address will not be published. Required fields are marked *

Table of Contents

Categories

Categories