Even though we now have the new Content Type Hub feature introduced in SharePoint Server 2010 for propagating columns and content types across all site collections in the farm, it can still be useful to export site columns from one site collection and import them into another. For example:
- When using SharePoint Foundation, where the Content Type Hub feature doesn’t exist
- Deploying a production environment with site columns created on a separate development or staging farm
- Keeping a record of the site columns created in a site collection for documentation or governance purposes
With PowerShell, we can use the column schema from a source site collection in SharePoint to generate an XML file, which can then be used to import the site columns into another site collection.
For this example I have created the following site columns under the “Custom Columns” group in my development site collection:
The PowerShell script below will export these site columns to an XML file called Script-SiteColumns.xml in the C:\Install folder. Note that the script looks at the group called “Custom Columns” to ensure columns 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-SiteColumns.xml"#Create Export Files
New-Item $xmlFilePath -type file -force#Export Site Columns to XML file
Add-Content $xmlFilePath "<?xml version=`"1.0`" encoding=`"utf-8`"?>"
Add-Content $xmlFilePath "`n<Fields>"
$sourceWeb.Fields | ForEach-Object {
if ($_.Group -eq "Custom Columns") {
Add-Content $xmlFilePath $_.SchemaXml
}
}
Add-Content $xmlFilePath "</Fields>"$sourceWeb.Dispose()
This script will generate an XML file similar to the one shown below.
Once you have the XML file, it can be used to import columns 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
$installPath = "C:\Install"
#Get exported XML file
$fieldsXML = [xml](Get-Content($installPath + "\Script-SiteColumns.xml"))
The final part of the script cycles through each field specified in the XML file, the properties associated with each column type, and then creates the column in the destination site. Whilst I have included the majority of properties associated with each type of site column (e.g., MaxLength, EnforceUniqueValues, Sortable, etc.), there may still be some properties you need to add yourself as I haven’t tested the script with every column type available in SharePoint:
$fieldsXML.Fields.Field | ForEach-Object {
#Configure core properties belonging to all column types
$fieldXML = '<Field Type="' + $_.Type + '"
Name="' + $_.Name + '"
ID="' + $_.ID + '"
Description="' + $_.Description + '"
DisplayName="' + $_.DisplayName + '"
StaticName="' + $_.StaticName + '"
Group="' + $_.Group + '"
Hidden="' + $_.Hidden + '"
Required="' + $_.Required + '"
Sealed="' + $_.Sealed + '"'
#Configure optional properties belonging to specific column types – you may need to add some extra properties here if present in your XML file
if ($_.ShowInDisplayForm) { $fieldXML = $fieldXML + "`n" + 'ShowInDisplayForm="' + $_.ShowInDisplayForm + '"'}
if ($_.ShowInEditForm) { $fieldXML = $fieldXML + "`n" + 'ShowInEditForm="' + $_.ShowInEditForm + '"'}
if ($_.ShowInListSettings) { $fieldXML = $fieldXML + "`n" + 'ShowInListSettings="' + $_.ShowInListSettings + '"'}
if ($_.ShowInNewForm) { $fieldXML = $fieldXML + "`n" + 'ShowInNewForm="' + $_.ShowInNewForm + '"'}
if ($_.EnforceUniqueValues) { $fieldXML = $fieldXML + "`n" + 'EnforceUniqueValues="' + $_.EnforceUniqueValues + '"'}
if ($_.Indexed) { $fieldXML = $fieldXML + "`n" + 'Indexed="' + $_.Indexed + '"'}
if ($_.Format) { $fieldXML = $fieldXML + "`n" + 'Format="' + $_.Format + '"'}
if ($_.MaxLength) { $fieldXML = $fieldXML + "`n" + 'MaxLength="' + $_.MaxLength + '"' }
if ($_.FillInChoice) { $fieldXML = $fieldXML + "`n" + 'FillInChoice="' + $_.FillInChoice + '"' }
if ($_.NumLines) { $fieldXML = $fieldXML + "`n" + 'NumLines="' + $_.NumLines + '"' }
if ($_.RichText) { $fieldXML = $fieldXML + "`n" + 'RichText="' + $_.RichText + '"' }
if ($_.RichTextMode) { $fieldXML = $fieldXML + "`n" + 'RichTextMode="' + $_.RichTextMode + '"' }
if ($_.IsolateStyles) { $fieldXML = $fieldXML + "`n" + 'IsolateStyles="' + $_.IsolateStyles + '"' }
if ($_.AppendOnly) { $fieldXML = $fieldXML + "`n" + 'AppendOnly="' + $_.AppendOnly + '"' }
if ($_.Sortable) { $fieldXML = $fieldXML + "`n" + 'Sortable="' + $_.Sortable + '"' }
if ($_.RestrictedMode) { $fieldXML = $fieldXML + "`n" + 'RestrictedMode="' + $_.RestrictedMode + '"' }
if ($_.UnlimitedLengthInDocumentLibrary) { $fieldXML = $fieldXML + "`n" + 'UnlimitedLengthInDocumentLibrary="' + $_.UnlimitedLengthInDocumentLibrary + '"' }
if ($_.CanToggleHidden) { $fieldXML = $fieldXML + "`n" + 'CanToggleHidden="' + $_.CanToggleHidden + '"' }
if ($_.List) { $fieldXML = $fieldXML + "`n" + 'List="' + $_.List + '"' }
if ($_.ShowField) { $fieldXML = $fieldXML + "`n" + 'ShowField="' + $_.ShowField + '"' }
if ($_.UserSelectionMode) { $fieldXML = $fieldXML + "`n" + 'UserSelectionMode="' + $_.UserSelectionMode + '"' }
if ($_.UserSelectionScope) { $fieldXML = $fieldXML + "`n" + 'UserSelectionScope="' + $_.UserSelectionScope + '"' }
if ($_.BaseType) { $fieldXML = $fieldXML + "`n" + 'BaseType="' + $_.BaseType + '"' }
if ($_.Mult) { $fieldXML = $fieldXML + "`n" + 'Mult="' + $_.Mult + '"' }
if ($_.ReadOnly) { $fieldXML = $fieldXML + "`n" + 'ReadOnly="' + $_.ReadOnly + '"' }
if ($_.FieldRef) { $fieldXML = $fieldXML + "`n" + 'FieldRef="' + $_.FieldRef + '"' }$fieldXML = $fieldXML + ">"
#Create choices if choice column
if ($_.Type -eq "Choice") {
$fieldXML = $fieldXML + "`n<CHOICES>"
$_.Choices.Choice | ForEach-Object {
$fieldXML = $fieldXML + "`n<CHOICE>" + $_ + "</CHOICE>"
}
$fieldXML = $fieldXML + "`n</CHOICES>"
}
#Set Default value, if specified
if ($_.Default) { $fieldXML = $fieldXML + "`n<Default>" + $_.Default + "</Default>" }
#End XML tag specified for this field
$fieldXML = $fieldXML + "</Field>"
#Create column on the site
$destWeb.Fields.AddFieldAsXml($fieldXML.Replace("&","&"))
write-host "Created site column" $_.DisplayName "on" $destWeb.Url
$destWeb.Dispose()
}
You may get some warning messages during processing of the import script if there are columns contained in the exported schema XML file that are already present in the destination site collection. Unless there are conflicting issues with your imported columns during testing, these warnings should be safe to ignore (or the columns removed from the exported XML if not required) as the script will not overwrite what is present in the site collection already. Once the script has been run, the custom site columns exported from the original site collection will be present in the new site collection:
In my next article, I cover exporting and importing content types from one site collection to another using a similar process…