SharePoint Jon

Converting Content Types, Records Center, and PowerShell


I recently started a project with a customer who wanted to implement a SharePoint Records Center and complex Record Retention Policies based around the age of documents, metadata, and Content Types. There was one major problem, the Client was currently using the out of the box “Document” Content Type across all sites and Site Collections and was using library specific Metadata.

My solution was to create Content Types whose Site Column Metadata matched that of the Metadata in specific libraries (using Managed Metadata was not practical for this Client) we then had to programmatically update the Content Types in every library before implement the Records Center, Content Organizer, and Retention Policies.

To do this, I wanted to be able to iterate through a Document Library, all of its Folders, and based conditionally around an existing Content Type, convert to another Content Type  while preserving Metadata including ‘Modified’ and ‘Modified By’ fields….Behold PowerShell to the rescue. 

I will openly admit, this script is not all entirely my original ideas, I leverage a few concepts from other individuals online and combined them together.

Feel free to use this script and modified it as needed.


#loading SharePoint Powershell Snapin
Add-PSSnapin Microsoft.SharePoint.PowerShell
write-host “setting web variable”
#The URL of the SharePoint site and subsite that contains the library
$web = Get-SPWeb “https://MySharePointSite/Subsite”
write-host “after setting web variable”
write-host “before setting list variable”
#below is where we define the Library name
#use the library name and not the library URL string.  Spaces are acceptable
$list = $web.Lists[“Documents”]
write-host “after etting list variable”
#Get Item by ContentType
write-host “before foreach item loop”
foreach ($item in $list.Items) {
    write-host “inside foreach item loop”
    #Inside the ‘if statement’ below, enter the name of your original content type
    #I left this as “Document”  
    #here is where we set the original content type name
    if($item.ContentType.Name -eq “Document”) {
        write-host “inside conditional ContentType logic”
        write-host “before modifying content type”
        # disable event firing / stop changing modified date
        $myAssembly = [Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”);
        $type = $myAssembly.GetType(“Microsoft.SharePoint.SPEventManager”);
        $prop = $type.GetProperty([string]”EventFiringDisabled”,[System.Reflection.BindingFlags] ([System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Static));
        $prop.SetValue($null, $true, $null);
        write-host “setting new content type”
        #here is where we enter the new content type name
        $item[“ContentType”] = “New ContentTypeName”
        write-host “saving changes to content type without modifing the Modified or Modified By Fields”
        # saving content type changes
        # enable event firing
        $prop.SetValue($null, $false, $null);