I was recently tasked with changing the template of some items in one of our client's Sitecore instances. Both the SourceTemplate and TargetTemplate had an image field, and part of the task was to transfer the value of the MainImage field of SourceTemplate to the PrimaryImage field of TargetTemplate. The templates looked similar to the following:

  • SourceTemplate
    • MainImage - Image field
  • TargetTemplate
    • Header - Single-Line Text field
    • PrimaryImage - Image field
    • SecondaryImage - Image field

Depending on the version of Sitecore PowerShell Extensions installed, you have two options.

PowerShell Extensions 4.5 or Higher

$rootItem = Get-Item master:/content;
$sourceTemplate = Get-Item "Source-Template-Path-Or-Guid-Here";
$targetTemplate = Get-Item "Target-Template-Path-Or-Guid-Here";

Get-ChildItem $rootItem.FullPath -Recurse | Where-Object { $_.TemplateName -eq $sourceTemplate.Name } | ForEach-Object {  
    Set-ItemTemplate -Item $_ -TemplateItem $targetTemplate `
        -FieldsToCopy @{ MainImage = "PrimaryImage" }
}

You can use the Set-ItemTemplate commandlet (documented here) to map the old fields to the new fields with the -FieldsToCopy parameter. Just pass the field map in this form: -FieldsToCopy @{ OldField1 = "NewField1"; OldField2 = "NewField2"; OldField3 = "NewField3" }.

Big thanks to Adam Najmanowicz for adding this nice commandlet!

PowerShell Extensions 4.4.1 or Lower

PowerShell Extensions 4.4.1 or lower require a bit more care to change templates:

$rootItem = Get-Item master:/content;
$sourceTemplate = Get-Item "Source-Template-Path-Or-Guid-Here";
$targetTemplate = Get-Item "Target-Template-Path-Or-Guid-Here";

Get-ChildItem $rootItem.FullPath -recurse | Where-Object { $_.TemplateName -eq $sourceTemplate.Name } | ForEach-Object {  
    $fieldValue = $_.MainImage;
    $_.ChangeTemplate($targetTemplate);
    $updatedItem = Get-Item $_.ID;
    $updatedItem.PrimaryImage = $fieldValue;
}

There are two big things to be careful of when changing item templates this way:

  1. Store the source field value(s) into a variable before you change the item's template.
  2. Get the updated item out of the database before you set the target field.

If you try to update the target field on $_ after changing the template without first retrieving the updated item from the database, an exception will be thrown that the target field does not exist on $_ and all of your items will have their template changed, but the original field values will be lost. If you try to pull the value out of your source field after changing the template, you will find that the source field is empty, and your original field values will be lost.

Closing Thoughts

Always make sure that you make a package of all items in your Sitecore instance before making changes to items with Sitecore PowerShell so that you have a backup if you make a mistake. If you aren't using Sitecore PowerShell Extensions, do yourself a favor and go get it!

Let me know your thoughts in the comments.

This post originally appeared on the Perficient Microsoft blog.