Just a short blog post today to share a Sitecore PowerShell script that I’ve recently found useful.

On a recent project, we took the decision to rework how we had been using placeholders across the site. This involved retiring a large number of placeholders that were currently in use, and replacing these with a much smaller set. Whilst everyone recognised the need to do this, the appetite for the work involved in updating the existing content was slim.

Fortunately, this sort of grunt work is just what SPE is perfect for. It didn’t take long to put a script together, and within minutes all of the content was updated. I’m sharing it in this post in case someone else finds it useful.

In our situation, we needed something that would process content items, find renderings that were on placeholder X and then update these to set the placeholder as Y. We also wanted to make sure that renderings on placeholders within those renderings were also catered for (e.g. a rendering on placeholder X/A would translate to Y/A). Further to this, we actually had a number of placeholder “mappings” such as this that we wanted updating all in one go.

This is the script that fixed the content:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$placeholderMappings = @(
@("/old-placeholder","/new-placeholder"),
@("/another-old-placeholder","/new-placeholder")
)
$rootItem = Get-Item -Path master:/sitecore/content/Home
$defaultLayout = Get-LayoutDevice "Default"
# Toggle for whether to update Shared or Final Layout
$useFinalLayout = $True
# If set to true, the script will only list the renderings that need fixing, rather than fixing them.
$reportOnly = $False
foreach ( $item in Get-ChildItem -Item $rootItem -Recurse )
{
# Only interested in items that have a layout
if (Get-Layout $item)
{
foreach( $mapping in $placeholderMappings )
{
# Get renderings in this item that have renderings in the placeholder we want to update
$renderings = Get-Rendering -Item $item -Placeholder ($mapping[0] + '/*') -Device $defaultLayout -FinalLayout:$useFinalLayout
foreach ( $rendering in $renderings )
{
# Only update the rendering if we're not in "Report Only" mode
if (!$reportOnly)
{
# Update the placeholder in the rendering and set it back in the item
$rendering.Placeholder = $rendering.Placeholder -replace $mapping[0], $mapping[1]
Set-Rendering -Item $item -Instance $rendering -FinalLayout:$useFinalLayout
}
Write-Host "$($item.FullPath) - Rendering $($rendering.UniqueID) - Placeholder: $($mapping[0]) --> $($mapping[1])"
}
}
}
}

That’s all there is to it. The general flow of the script is:

  • Recurse through all items with layouts in the content folder specified
  • For each placeholder mapping specified:
    • Get any renderings that match the old placeholder (an exact match or ones that begin with it)
    • Replace the old placeholder with the new one
    • Set the rendering back into the item

There are two variables you can tweak in the script: one for determining whether to update the Shared or Final Layout, and the other to run the script in “Report Mode” where it will just find items that require changes, without actually going ahead and making the update.

I hope that proves useful to someone!