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" |
Want to talk?
Drop us a line. We are here to answer your questions 24*7.