Monday, January 14, 2013

Document Sets in a SharePoint 2010 Library Template

Recently I needed to create a SharePoint Library template w/ content for a client. They had over 300 document sets with 3 metadata fields that they wanted inside the template. Each year they needed to create a new library with this exact same layout, so saving a document library as a template seemed like the perfect fit.

I created the library, created all the document sets and setup all the metadata for each one and then saved that library as a template.

Unfortunatey when I created a new library based on my shiny new template, all the document sets were generated as Folders and errored out when I tried to access them. Once I manually changed the content type from Folder to my Document Set content type, all worked fine and all metadata fields had the proper values.

So this lead me to research how I could quickly modify over 300 folders content types to the Document Set type.

I then stumbled on this great article by Phil Childs on Changing the Content Type Set on Files in SharePoint.

This PowerShell didn't quite do what I needed it to do however, as it was just looking at the Items and not the Folders, so I modified it slightly to produce what I wanted. My change required creating an array of the Folders IDs as updating a folder changes the collection and would error out of a ForEachObject loop.

Here's what I came up with:
function Reset-SPFolderContentType ($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
	$folderIds = @()
	$list.Folders | ForEach-Object {
		$folderIds = $folderIds + $_.ID
	}
	ForEach ($folderId in $folderIds) {
            #Check if the item content type currently equals the old content type specified
	    $item = $list.GetItemById($folderId)
            if ($item.ContentType.Name -eq $oldCT.Name)
            {
                    #Change the content type association for the item
                    write-host "Resetting content type for file" $item.Name "from" $oldCT.Name "to" $newCT.Name
                    $item["ContentTypeId"] = $newCTID
                    $item.Update()
            }
            else
            {
                write-host "File" $item.Name "is associated with the content type" $item.ContentType.Name "and shall not be modified"
            }
        }
    }
    else
    {
        write-host "One of the content types specified has not been attached to the list"$list.Title
    }
    $web.Dispose()
}

To use it, you copy the entire function, open a SharePoint PowerShell command prompt and paste it in. Hit enter until the >> is no longer you prompt. Then you can use the function like so:

Reset-SPFolderContentType –WebUrl “http://sharepoint/sites/audit” –ListName “2002” –OldCTName “Folder” –NewCTName “Audit Document Set”

Thanks Phil!
- Owen Runnals
SharePoint Practice Manager @ General Networks Corp

No comments:

Post a Comment