Synchronize SDL Web components with schemas using PowerShell
# Usage examples
# .\item-sync.ps1 "tcm:0-5-1" Sync in dry-run mode, the -Update flag is needed to actually make changes to the items
# .\item-sync.ps1 "-ItemId tcm:0-5-1" Sync all components and pages in a publication
# .\item-sync.ps1 "-ItemId tcm:5-32-2" Sync all items in a folder and subfolders
# .\item-sync.ps1 "-ItemId tcm:0-5-1 -Update" Sync and save changes
# .\item-sync.ps1 "-ItemId -Verbose"
# Prerequisite: Install the tridion-powershell-modules https://github.com/pkjaer/tridion-powershell-modules
#todo implement [Switch]$Whatif for the dry-run
#todo change -Update switch to the more standard -Confirm [switch]$confirm=$true
param (
[parameter(Mandatory=$true)]
[string] $ItemId,
[parameter(Mandatory=$false)]
[switch] $Update
)
$ErrorActionPreference = "Stop"
function SynchronizeItem ($item, $updateAfterSynchronize)
{
$itemId = $item.Id
$itemTitle = $item.Title
Write-Verbose ("Synchonizing item {0} {1}" -f $itemId, $itemTitle)
$options = New-Object Tridion.ContentManager.CoreService.Client.SynchronizeOptions
#The ApplyDefaultValuesForMissingOptionalFields is not used, this would add unnessesary data to the items
$options.SynchronizeFlags = [Tridion.ContentManager.CoreService.Client.SynchronizeFlags]::FixNamespace -bor
[Tridion.ContentManager.CoreService.Client.SynchronizeFlags]::RemoveUnknownFields -bor
[Tridion.ContentManager.CoreService.Client.SynchronizeFlags]::RemoveAdditionalValues -bor
[Tridion.ContentManager.CoreService.Client.SynchronizeFlags]::ApplyDefaultValuesForMissingMandatoryFields -bor
[Tridion.ContentManager.CoreService.Client.SynchronizeFlags]::ApplyFilterXsltToXhtmlFields -bor
[Tridion.ContentManager.CoreService.Client.SynchronizeFlags]::ConvertFieldType
if ($updateAfterSynchronize)
{
$result = $client.SynchronizeWithSchemaAndUpdate($itemId, $options);
}
else
{
$result = $client.SynchronizeWithSchema($item, $options);
}
if($result.SynchronizationActions.count -eq 0) {
Write-Verbose "no actions"
} else {
Write-Output ("Synchonized item {0} {1}" -f $itemId, $itemTitle)
foreach ($action in $result.SynchronizationActions)
{
Write-Output (" Field Name: {0} - Field Index: {1} - Action Taken: {2}" -f $action.FieldName, $action.FieldIndex, $action.SynchronizationActionApplied)
}
}
}
if($Update) {
Write-Output "Running item-schema synchronization with update; The component and page changes will be saved"
} else {
Write-Output "Running item-schema synchronization in dry run; No component and page changes will be s
aved"
}
Write-Verbose "Create Core Service client"
Import-Module Tridion-CoreService -Verbose:$false
Set-TridionCoreServiceSettings -Version "2013-SP1"
$client = Get-TridionCoreServiceClient
#todo add options to limit amount of items, i.e. query by schema
$searchQuery = New-Object Tridion.ContentManager.CoreService.Client.SearchQueryData
$link = New-Object Tridion.ContentManager.CoreService.Client.LinkToIdentifiableObjectData
$link.IdRef = $ItemId
$searchQuery.SearchIn = $link
$searchQuery.SearchInSubtree = $true
$searchQuery.ItemTypes = [Tridion.ContentManager.CoreService.Client.ItemType]::Component, [Tridion.ContentManager.CoreService.Client.ItemType]::Page
Write-Verbose "Query components and pages"
$searchQuery.BlueprintStatus = [Tridion.ContentManager.CoreService.Client.SearchBlueprintStatus]::Local
$localItems = $client.GetSearchResults($searchQuery)
Write-Verbose ("Found {0} local items to synchronize" -f $localItems.Count)
Write-Verbose "Query components and pages"
$searchQuery.BlueprintStatus = [Tridion.ContentManager.CoreService.Client.SearchBlueprintStatus]::Localized
$localizedItems = $client.GetSearchResults($searchQuery)
Write-Verbose ("Found {0} localized items to synchronize" -f $localizedItems.Count)
$items = $localItems + $localizedItems
Write-Output ("Found {0} items to synchronize" -f $items.Count)
Write-Output "Synchronizing items"
ForEach ($item in $items)
{
Try
{
if($Update)
{
SynchronizeItem $item $true
}
else
{
SynchronizeItem $item $false
}
}
Catch {
Write-Output ("Error syncing item {0}: {1}" -f $item.Id, $_.Exception.Message)
}
}