Sharepoint – Propagate site column to list.

After searching time, I find a great article about propagating updates in site content type to child contents. In this, he said “When you use a site collection content type on a list, what actually happens is a “copy” of the original content type is made and stored in the list. Thus, any changes to the original content type is not propagated into the list”. As MS explains it:

“Do not, under any circumstances, update the content type definition file for a content type after you have installed and activated that content type. Windows SharePoint Services does not track all the changes made to the content type definition file. Therefore, you have no reliable method for pushing down all the changes made to site content types to the child content types.”

More on the article can read here: https://johanleino.wordpress.com/2009/08/11/propagating-updates-to-content-types/

His solution is used c#. In my case I need to process by powershell. Here is my solution:


param
(
 [string]$SiteUrl
)

if ( (Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{
 Add-PsSnapin Microsoft.SharePoint.PowerShell
}

function PropagateFieldToList()
{
 if($list.Fields.ContainsField($fieldOnWeb.InternalName) -eq $true)
 {
 $fieldInList = $list.Fields[$fieldOnWeb.Id]
 $fieldInList.SchemaXml = $fieldOnWeb.SchemaXml
 $fieldInList.Update()
 Write-Host "Propagate field $field to Page library on $web."
 }
 else
 {
 $list.Fields.Add($fieldOnWeb)
 $list.Update()
 Write-Host "Add field '$($fieldOnWeb)' to page list."
 }

 AddColumnToContentType "ContentTypeName" $fieldOnWeb $false
}

function AddColumnToContentType($ctype, [Microsoft.SharePoint.SPField] $field, $isRequireField) {
 if ($ctype.FieldLinks[$field.InternalName] -eq $null) {
 $fieldLink = New-Object Microsoft.SharePoint.SPFieldLink($field)
 $fieldLink.Required = $isRequireField;
 $ctype.FieldLinks.Add($fieldLink);
 $ctype.Update()
 Write-Host "Add field $field to content type $($ctype.Name)."
 }
}

try
{
 $site = get-SPSite $SiteUrl
 $rootweb = $site.RootWeb
 $fieldOnWeb = $rootweb.Fields.GetFieldByInternalName('FieldInternalName')
 if($fieldOnWeb -ne $null)
 {
 foreach ($web in $rootweb.Webs)
 {
 $pageLibName = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPagesListName($web)
 $list = $web.Lists[$pageLibName]
 PropagateFieldToList
 }
 }
}
finally
{
 if ($site -ne $null)
 {
 $site.Dispose()
 }
}

Hope

Leave a comment