Microsoft

Sitecore PowerShell – Change Item Template and Retain Field Value

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" }
}
Microsoft - The Essential Guide to Microsoft Teams End-User Engagement
The Essential Guide to Microsoft Teams End-User Engagement

We take you through 10 best practices, considerations, and suggestions that can enrich your Microsoft Teams deployment and ensure both end-user adoption and engagement.

Get the Guide

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.5 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 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.

About the Author

I'm a Sitecore MVP and Lead Technical Consultant at Perficient focusing on Sitecore and custom .NET development.

More from this Author

Thoughts on “Sitecore PowerShell – Change Item Template and Retain Field Value”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to the Weekly Blog Digest:

Sign Up
Categories