Thursday, February 23, 2012

Export and Import Content Types


Recently we needed to migrate custom content types from one web application to another.

I tried the most straight-forward approach first: use the new content type hub feature of the Managed Metadata Service App. The idea was to mark the site collection containing these content types as content type hub, and essentially subscribe the rest of the site collections to consume from it.
Due to the way they were originally created, we kept getting errors trying to use this.

 After digging around for a while, the solution was to break down the process in two steps: work with site columns first, and then work with content types based on these columns:

  1. Export custom site columns from the original site collection: results will go into  site columns xml file. For this I used sitecolumn utility from Codeplex.
  2. Export custom content data types from the original site collection: this will create xml file with definitions for content types from  the content type group you filter on
  1. Import custom site columns from the exported site columns xml file : again Codeplex
  1. Re-create custom content types in the target site


$sourceWeb = Get-SPWeb http://portal
$xmlFilePath = "C:\Install\Script-SiteContentTypes.xml"
#Create Export File
New-Item $xmlFilePath -type file -force
#Export Content Types to XML file
Add-Content $xmlFilePath ""
Add-Content $xmlFilePath "`n"
$sourceWeb.ContentTypes | ForEach-Object {
    if ($_.Group -eq "Custom Content Types") {
        Add-Content $xmlFilePath $_.SchemaXml
    }
}
Add-Content $xmlFilePath ""
$sourceWeb.Dispose()

$destWeb = Get-SPWeb http://portal/sites/migrationtest
$xmlFilePath = "C:\Install\Script-SiteContentTypes.xml"



#Create Site Content Types
$ctsXML = [xml](Get-Content($xmlFilePath))
$ctsXML.ContentTypes.ContentType | ForEach-Object {
    #Create Content Type object inheriting from parent
    $spContentType = New-Object Microsoft.SharePoint.SPContentType ($_.ID,$destWeb.ContentTypes,$_.Name)
   
    #Set Content Type description and group
    $spContentType.Description = $_.Description
    $spContentType.Group = $_.Group
   
    $_.Fields.Field  | ForEach-Object {
        if(!$spContentType.FieldLinks[$_.DisplayName])
        {
            #Create a field link for the Content Type by getting an existing column
            $spFieldLink = New-Object Microsoft.SharePoint.SPFieldLink ($destWeb.Fields[$_.DisplayName])
       
            #Check to see if column should be Optional, Required or Hidden
            if ($_.Required -eq "TRUE") {$spFieldLink.Required = $true}
            if ($_.Hidden -eq "TRUE") {$spFieldLink.Hidden = $true}
       
            #Add column to Content Type
            $spContentType.FieldLinks.Add($spFieldLink)
        }
    }
   
    #Create Content Type on the site and update Content Type object
    $ct = $destWeb.ContentTypes.Add($spContentType)
    $spContentType.Update()
    write-host "Content type" $ct.Name "has been created"
}
$destWeb.Dispose()

This script has been taken from Phil Childs' blog which can be found  here , so big thanks to him.

1 comment:

  1. thnx for the article
    i tried to run the same, but i am not getting all teh content types from the source site collec to destination site collec. am getting the below error:
    am trying to get only a single content type and its missing in the destination site.
    can you help how to resolve this?


    Exception calling "Add" with "1" argument(s): "A duplicate content type "Basic Content Type" was found."
    At C:\Maddy\Scripts\ImportBIFPageCTypetoWebFromXML.ps1:35 char:5
    + $ct = $destWeb.ContentTypes.Add($spContentType)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SPException

    Exception calling "Update" with "0" argument(s): "The object has been updated by another user since it was last fetched."
    At C:\Maddy\Scripts\ImportBIFPageCTypetoWebFromXML.ps1:36 char:5
    + $spContentType.Update()
    + ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SPException

    ReplyDelete