Wednesday, 9 February 2011

Export and import/create site content types in SharePoint using PowerShell

In my previous article, I ran through how to export custom site columns from one site collection and import them into another site collection using PowerShell. In this article, I will be following the same process, but this time for copying site content types from one site collection to another.

As described previously, SharePoint Server 2010 does contain the new Content Type Hub feature for distributing site columns and content types across multiple site collections, but there still may be scenarios where the feature cannot be used – e.g., if using SharePoint Foundation, migrating columns and content types between farms, or for documenting an environment.

As with the previous site column article, we can use PowerShell to export the content type schema from a source site collection into an XML file, which can then be used to import the same content types into another site collection.

Please note (Part 1): The script used here assumes that you have already migrated the site columns used in the these content types to the destination site collection. You could, of course, write a combined script that covers exporting/importing both site columns and content types to ensure the whole process is dealt with as a one-click operation.

Please note (Part 2): The script only supports creating the content type in a destination site and associating the appropriate site columns to it. It does not copy across other features of the content type – e.g., workflow associations, information management policies, document template, etc. – although you could expand the script to support extra features, if required.

For this example, I have created the following site content types under the “Custom Content Types” group in my development site collection:

image

I have also added a required “Description” column to the “Company Document” content type (from which the other custom content types inherit) and an optional “Category” column to the “IT Document” content type.

The PowerShell script below will export these content types to an XML file called Script-SiteContentTypes.xml in the C:\Install folder. Note that the script looks at the group called “Custom Content Types” to ensure content types created by a standard SharePoint installation are not included in the export. You will need to ensure that appropriate custom group name(s) are specified in your script when exporting:

$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 "<?xml version=`"1.0`" encoding=`"utf-8`"?>"
Add-Content $xmlFilePath "`n<ContentTypes>"
$sourceWeb.ContentTypes | ForEach-Object {
    if ($_.Group -eq "Custom Content Types") {
        Add-Content $xmlFilePath $_.SchemaXml
    }
}
Add-Content $xmlFilePath "</ContentTypes>"

$sourceWeb.Dispose()

This script will generate an XML file similar to the one shown below.

image

Once you have the XML file, it can be used to import the content types into another site collection by using the script below. The first part of the script gets the destination Web URL and exported XML file:

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

The final part of the script cycles through each content type specified in the XML file, creates the content type with the exported description and group name, and finally reads in each column associated with the exported content type and wires them up to the new content type in the destination site collection, specifying if they are hidden or required columns during the process.

#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()

Once the script has been run, the custom site content types exported from the original site collection will be present in the new site collection…

image

…with the “Description” and “Category” columns linked to them as expected.

image

51 comments:

  1. Perfect - just what i needed - THANKS.

    ReplyDelete
  2. Getting an error:
    Constructor not found for New-Object Microsoft.SharePoint.SPFieldLink

    ReplyDelete
  3. I'm having the same issue as user before me: New-Object : Constructor not found. Cannot find an appropriate constructor for type Microsoft.SharePoint.SPFieldLink.
    At C:\Scripts\ImportCT.ps1:19 char:38

    Any ideas, please?

    ReplyDelete
    Replies
    1. I had the same issue and found that the problem was with a feature not activated.

      In my scenario the content type was based off the "Document" content type and I had "Document ID Service" turned on in the source site collection features. I turned on the feature in my destination site collection and deleted the previously imported content types. I re-ran the import again with no errors.

      thanks for the script Phil!

      Delete
    2. Chandra Shekhar24 April 2012 at 08:19

      You will face this issue if you have not imported the "Site Columns" to destination web before importing the content types. Please go thru the previous article "http://get-spscripts.com/2011/01/export-and-importcreate-site-columns-in.html" for importing the "Site Columns".

      Thanks Phil for the contribution :)

      Delete
    3. I'm getting the same error New-Object : Constructor not found. Cannot find an appropriate constructor for type Microsoft.SharePoint.SPFieldLink... but the columns are successfully added.... Any thoughts???

      Delete
    4. @Peter Mendez
      Thanks for info about "Document ID Service"

      Delete
  4. Wonderful blog! I found it while searching on Yahoo News. Do you have any tips on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Many thanks.sbobet

    ReplyDelete
  5. Thanks allot, it works like a charm.
    Cheers
    Alex

    ReplyDelete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. Great help! I'm working through the SPFiledLink error mentioned above as well (it's not the DocumentID service, but is likely some other dependency). In any case, it's helpful to have a way to clear the incomplete content types so I can try again. Here's a script to do that:

    Of course, this will delete all content types for the $group specified. Hope you are using groups effectively!

    $sourceWeb = Get-SPWeb http://yourdestsite;
    $group = "your group name";

    for ($i=$sourceWeb.ContentTypes.Count; $i -gt 0; $i--)
    {
    $thisType = $sourceWeb.ContentTypes[$i - 1];
    if ($thisType.Group -eq $group) {
    $sourceWeb.ContentTypes.Delete($thisType.Id);
    }
    }

    ReplyDelete
  8. Thanks for the contribution, dfosterh!

    ReplyDelete
  9. Thanks for the powershell script, I have a question.
    Normally the schema for content type will not include those columns that from parent.
    just like below, with this script parent columns will also include in the output xml file.
    result my document library display form showing duplicate name and title columns.
    Should I remove those columns manually or I'm doing something wrong?

    ReplyDelete
  10. Hello, thank you for putting up this information. One thing I'd like to do is export information about custom content types to an xml file in order to keep track of them. As far as I can tell there is no data on a content type's parent type in the xml generated by your solution. Could you advise me on how to accomplish this?

    ReplyDelete
  11. Phil

    Thanks for sharing this wonderful article.

    We have list out own custom content type for different sites and their document library. How can I import my own custom content type and set it for each assigned document library.

    Please advise

    Avian

    ReplyDelete
  12. Thank you for the post. The script works for the top level site i.e http://portal but does not return any results for http://portal/testing/ear which is the top level site of a site collection.

    ReplyDelete
  13. I have a custom group and have a custom content type in that group. Script above doesn't work for me. what should I need to change to make sure I can export and then import the content type.

    My custom content type name: Informatics General Documents
    My custom group name: Informatics Content Types

    Please advise.
    Mdeveloper

    ReplyDelete
  14. Helped to solve a massive issue for me. Thank you.

    ReplyDelete
  15. Very helpful series of posts. It would be more helpful if your XML file was downloadable or text-selectable so I could see more of it. I'm hacking this series to get content types and columns that were deployed as features to 2007 imported into the syndication hub of 2010. Getting my XML right is proving to be the only real issue.

    ReplyDelete
  16. Greetings from the nordics, you save my Friday! Thanks!

    ReplyDelete
  17. Is this code work for sharepoint 2007? I think there is a problem with SpContenttype constructor.
    Plz suggest a right way to go with 2007.

    ReplyDelete
  18. Excellent piece of work - thanks Phil!

    ReplyDelete
  19. Thanks, but doesn't work for me, gives me an empty xml file.

    Please help

    ReplyDelete
  20. Thanks! Works great
    What about Document Set? is that possible?

    ReplyDelete
  21. Thank you again! You are appreciated!

    I didn't get the results I expected on this or the Custom Columns script on the first try, but realized that I had to change the "Custom List" to "{customized name of client} Custom List" and then got the right xml! Wonderful!

    Doug
    Codesigned.com

    ReplyDelete
  22. Thanks, just one question; will this procedure work if I'm importing/exporting content types from one farm to another?

    thank you.

    ReplyDelete
  23. I was also thinking same as Msemish, wanting to become more efficient between projects with reusable content types. Can this be used on different farms? Also has anyone tested that these powershell scripts (site columns also) work in SP2013 ?

    ReplyDelete
  24. thanks..very helpful...

    I have few calculated columns which are successfully exported to xml but when re-creating CT , they are not appearing...if you can suggest something it will be grateful...

    ReplyDelete
  25. Hi,
    i'm getting error: This constraint cannot be enabled as not all values have corresponding parent values.

    Have yoiu any idea, what can be a problem?

    Thank you

    ReplyDelete
  26. Hi,
    we are using Taxonomy fields Inside Documentsets. The Problem is that the fields "TaxCatchAllLabel" and "_dlc_DocIdUrl" can't be added, throws an error? Any idea what we can do?

    ReplyDelete
  27. I also use taxonomy fields in 2013, I get now a Problem with importing CT again: Exception calling "Add" with "1" argument(s): "A duplicate field name "b4acd0e1d410426ca650c4544f259150" was found." This is raised for every taxonomy field, yes they are already imported and available. But I found in XML to times the same field with the same ID, one of type note and one of type taxonomyfieldtype ... what is wrong? And I have also the SPFiledLink Problem and it is not caused by dependencies. Maybe Version 2013?

    ReplyDelete
  28. I love your code. It always works perfectly for me and I learn so much from it.

    ReplyDelete
  29. Thanks for sharing this information related to Export and import/create site content types
    to SharePoint online. This is the best way to export content types but spend more time so I used the automate Migrator for Documents tool(http://www.lepide.com/lepidemigratordocuments/) which helps to transfer content to SharePoint instantly. This Migration tool provides an easy way for system administrator to execute task of SharePoint Online migration.

    ReplyDelete
  30. I know this is an old thread now but I've just used the Export/Import Site Column scripts which worked perfectly first time but the Content Type scripts are giving me problems...
    The string starting:
    At D:\scripts\ExportContentTypes.PS1:15 char:42
    + Add-Content $xmlFilePath " <<<< "
    is missing the terminator: ".
    At D:\scripts\ExportContentTypes.PS1:16 char:21
    + $sourceWeb.Dispose() <<<<
    + CategoryInfo : ParserError: (
    $sourceWeb.Dispose():String) [], ParseException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

    I've copied and pasted the script from the code snipet above, just like I did with the Site Column scripts.
    I've even used Notepad ++ to find and replace all of the ` " ( ) < > { } characters but it's not helped.

    Am I missing something really simple?
    There's nothing wrong with the position of the stated character in that error is there?
    N03L.

    ReplyDelete
  31. I've found my mistake. I'd somehow missed a " from the front of the XML path.

    ReplyDelete

  32. تنتشر الحشرات صيفا بسب ارتفاع درجة الحرارة والرطوبة فاغلب مناطق المملكة تعانى من انتشار عدة انواع من الحشرات للتغلب عليها لابد من الاستعانة بشركة مختصة باعمال
    مكافحة الحشرات المختلفه فكل حشرة تحتاج الى مبيد خاص بها ليتم القضاء النهائي عليها
    يمكنك دوما الاستعانة بافضل شركة مكافحة حشرات بالرياضفهى تقدم افضل مكافحة للحشرات باستخدام افضل المبيدات وبدون مغادرة المكان

    وتعد الاول الاشمل في مكافحة الحشرات فهى تعد افضل شركة مكافحة حشرات بابها و افضل واحسن شركة مكافحة الحشرات بالاحساء وافضل شركة مكافحة حشرات بينبعوافضل شركة مكافحة حشرات بالجبيل وافضل شركة مكافحة حشرات بجدة و افضل شركة مكافحة حشرات بمكة وافضل شركة مكافحة حشرات بالخرج وافضل شركة مكافحة حشرات بالقصيموافضل شركة مكافحة حشرات بالخبر وافضل شركة مكافحة حشرات بالمدينة المنورة

    ReplyDelete

  33. شركة ابو سمره لجميع متطلبات المنزل
    شركتنا الأفضل لنقل الاثاث بالرياض شركة نقل اثاث بالرياض
    تعمل على تقديم افضل الخدمات للزبون من سرعة الاداء وجودة العمل والمحافظه على ممتلكات المنزل ,شركة عزل خزانات شركة مميزه شركة عزل خزانات بالرياض
    كما انها شركة لتنظيف الخزانات بالرياض شركة تنظيف خزانات بالرياض
    شركتنا بها تخزين اثاث بالرياض تعمل على تخزين الاثاث بنظام شركة تخزين اثاث بالرياض
    شركتنا تعد المميزه فى شركات مكافحة الحشرات فى الرياض شركة تخزين اثاث بالرياض
    شركتنا ممتازه فى تنظيف الشقق والفلل بعمل جاد شركة تنظيف شقق بالرياض
    شركة تنظيف بالرياض شركة تنظيف فلل بالرياض
    شركة تنظيف بالرياض
    وايضا شركة تنظيف موكيت باتقان بالرياض بالمنظفات عالية الجودهشركة تنظيف موكيت بالرياض
    يوجد لدينا شركة تسليك مجارى وايضا تنظيف بيارات بالمهاره الكامله شركة تسليك مجارى بالرياض
    شركة تنظيف البيارات بالرياض شركتنا تعمل فى الصيانه والترميم بالرياض
    شركة صيانة وترميم بالرياض
    شركتنا تنفرد فى مهارة رش المبيدات دون التاثير على صحة الزبون او العمال شركة رش مبيد بالرياضشركة رش مبيدات بالرياض
    شركة ابو سمره بها عمال لكشف تسربات المياه بالرياض شركة كشف تسربات المياه بالرياض

    ReplyDelete
  34. Nice post, thanks for sharing this wonderful and useful information with us.
    Visit our website:
    A case for trade invoicing in INR
    www.indianwesterlies.blogspot.com

    ReplyDelete
  35. Best post, thanks for sharing such a wonderful post.
    Visit our website:
    IEC code online
    www.indianwesterlies.blogspot.com

    ReplyDelete