I came across a need to change all existing documents in a Site Collection to another ContentType, but without changing data like, “modified by” or “modified date”.

Why?

I need to attach a column to all documents and it’s just not good practise to add columns to the default “Document” ContentType. I need to add the ContentType to the Document library, attach all documents with the ContentType “Document” to the new ContentType and then delete the ContentType “Document”. Users need not think about ContentTypes and how to use the correct one, so this needs to run once a day to catch new document libraries and change the documents without the users noticing anything.

The plan for each document library:

  1. Add ContentType “MyCustomDocument”
  2. Enable versioning (major versions and no limits)
  3. Attach all documents to the ContentType “MyCustomDocument”
  4. Remove the standard ContentType “Document”
  5. Create Scheduled tasks for the whole process

I have created two PowerShell scripts in order for this to complete. One script takes care of the documentlibrary and another script takes care of all the documents in those libraries. If you run the scripts manually, you need to run the first script twice, as it will only run, when all documents in the library has changed their ContentType to the new one.

Check out the scripts below or download the files, including bat-files to start the scripts. Download PowerShell files and batch files to start them up.

CleanUpDocLibs.ps1

&lt;#Name: CleanUpDocLibs.ps1Title: Clean Up Document LibrariesAuthor: Ulrich Gerting Bojko (ulrich@getinthesky.com)Description: Go through all Libraries (execpt the ones in the forbidden list)and do the following:1. Allow Content Types2. Enable Versioning (major versions, no limit)3. Attach Content Type "MyCustomDocument"4. Delete Content Type "Document"#&gt;#Fill ind the url of the sitecollection you wish to run through$url = "http://intranet.domain.com"#Fill in the Content Type you wish to add to the library$lookForCT = "MyCustomDocument"#Fill in the Content Type you wish to delete$lookForCTDel = "Document"#Fill out the names of those documentlibraries that should be excluded below$forbidden = @("Style Library", "FormServerTemplates", "SiteCollectionDocuments", "SiteAssets")#Do not edit below this line and blame me for anything gone wrong#------------------------------------------------------------------------------#Add the SharePoint snapin and continueAdd-PSSnapin Microsoft.SharePoint.Powershell -ea SilentlyContinue$site = Get-SPSite $url#Walk through each site in the site collection$site | Get-SPWeb -Limit all | ForEach-Object {$web = $_.Url<pre><code>#Go through each document library in the site$_.Lists | where { $_.BaseTemplate -eq &amp;quot;DocumentLibrary&amp;quot;} | ForEach-Object {     $docLibrary = $_.Lists[$_.Title]    #Check if List is forbidden    if ($forbidden -contains $_.Title ){    }    else    {        if (($_.ContentTypes | where { $_.Name -eq $lookForCT }) -eq $null)        {            write-host &amp;quot;Adding content type &amp;quot; $lookForCT &amp;quot;on list&amp;quot; $docLibrary.Title            $docLibrary.ContentTypesEnabled = $true                        $docLibrary.EnableVersioning = $true            $docLibrary.Update()            #Add site content types to the list            $ctToAdd = $site.RootWeb.ContentTypes[$lookForCT]            $ct = $docLibrary.ContentTypes.Add($ctToAdd)            write-host &amp;quot;Content type&amp;quot; $ct.Name &amp;quot;added to list&amp;quot; $docLibrary.Title            $docLibrary.Update()        }        #Delete Content Type        if (($_.ContentTypes | where { $_.Name -eq $lookForCTDel }) -eq $null)        {            #write-host &amp;quot;No content type exists with the name&amp;quot; $lookForCTDel &amp;quot;on list&amp;quot; $_.Title        }        else        {            $ctToRemove = $_.ContentTypes[$lookForCTDel]            write-host &amp;quot;Removing content type&amp;quot; $ctToRemove.Name &amp;quot;from list&amp;quot; $web &amp;quot;/&amp;quot; $_.Title            $_.ContentTypes.Delete($ctToRemove.Id)            $_.Update()        }    }}</code></pre>}#Dispose of the site object$site.Dispose()

CleanUpItems.ps1

&lt;#Name: CleanUpItems.ps1Title: Clean Up Files in Document LibrariesAuthor: Ulrich Gerting Bojko (ulrich@getinthesky.com)Description: Go through all files in all Documentlibraries, thathave the new Content Type attached and do the following:1. Change the Content Type to the new one2. Preserve the "Modified" and "Editor" metadata#&gt;#Fill ind the url of the sitecollection you wish to run through$url = "http://intranet.domain.com"#Fill in the name of the Content Tpe you wish to replace from$OldCTName = "Document"#Fill in the name of the Content Tpe you wish to replace to$NewCTName = "MyCustomDocument"#Do not edit below this line and blame me for anything gone wrong#------------------------------------------------------------------------------#Add the SharePoint snapin and continueAdd-PSSnapin Microsoft.SharePoint.Powershell -ea SilentlyContinue$site = Get-SPSite $url#Walk through each site in the site collection$site | Get-SPWeb -Limit all | ForEach-Object {<pre><code>$web = $_.Url       #Go through each document library in the site$_.Lists | where { $_.BaseTemplate -eq &amp;quot;DocumentLibrary&amp;quot;} | ForEach-Object {$list = $_$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)            {                #Check the check out status of the file                if ($_.File.CheckOutType -eq &amp;quot;None&amp;quot;)                {                    #Change the content type association for the item                    $item = $_                    $Editor = $item[&amp;quot;Editor&amp;quot;]                    $Modified = $item[&amp;quot;Modified&amp;quot;]                    $_.File.CheckOut()                    write-host &amp;quot;Resetting content type for file&amp;quot; $web &amp;quot;/&amp;quot; $_.Url &amp;quot;from&amp;quot; $oldCT.Name &amp;quot;to&amp;quot; $newCT.Name                    $_[&amp;quot;ContentTypeId&amp;quot;] = $newCTID                    $item[&amp;quot;Editor&amp;quot;] = $Editor                    $item[&amp;quot;Modified&amp;quot;] = $Modified                    $_.Update()                    $_.File.CheckIn(&amp;quot;Content type changed to &amp;quot; + $newCT.Name, 1)                }                else                {                    write-host &amp;quot;File&amp;quot; $web &amp;quot;/&amp;quot; $_.Url &amp;quot;is checked out to&amp;quot; $_.File.CheckedOutByUser.ToString() &amp;quot;and cannot be modified&amp;quot;                }            }            else            {                write-host &amp;quot;File&amp;quot; $web &amp;quot;/&amp;quot; $_.Url &amp;quot;is associated with the content type&amp;quot; $_.ContentType.Name &amp;quot;and shall not be modified&amp;quot;            }        }    }    else    {        #write-host &amp;quot;One of the content types specified has not been attached to the list&amp;quot;$web $list.Title    }}</code></pre>}#Dispose of the site object$site.Dispose()


Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.