Sitecore PowerShell Extension (SPE) is the most powerful module that I have ever used. It can greatly reduce your efforts of maintaining the Sitecore Contents. And It can also be used to pull some useful reports.
Thanks to the creators- It’s an open source. There are many blogs about SPE and it has some very good documentation that can help you get started. I was aware of it’s existence long back. Since I had zero experience on PowerShell, I never really gave it a try.
Things got changed when I Installed Sitecore 9 via the PowerShell Scripts and thanks to some of the build scripts I came across that were written in PowerShell, I got quite familiar with it’s semantics. So right when I got myself into a situation where I thought, SPE might help me, I jumped straight into it.
I guess we could agree on how terrible, Authoring and Managing the Content could become. Esp. if it’s a multi lingual/multi site environment. SPE could turn hours of work to minutes.(Trust me I am not overselling it). Well, to me right when you setup your UAT/PRE-PROD environment, along with the installation of Sitecore in those environment, you should setup SPE as well.
Setting Up – SPE Installation is simple and straight forward. Just like installing a package. You can refer the official documentation for Setup and Installation
Sharing here some of my PowerShell Scripts, (Hoping to add more as I get more hands-on). These have some simple Scripts like getting an item/child item/child item based on condition and item’s rendering etc as well. (Basics!!!)
- Get Items with a Specific Rendering and update it’s data source (You can modify the same script to add a certain rendering/data source to all the items)
$rendering = Get-Item -Path “master:Rendering-Path”
$items = Get-ChildItem -Path “master:Parent Item Path” -Recurse | Where-Object { Get-Rendering -Item $_ -FinalLayout -Rendering $rendering }
$DatasourceId = “{DataSource Item ID}”
write-host $items.Count
foreach($item in $items) {
$renderingInstance = Get-Rendering -Item $item -FinalLayout -Rendering $rendering
if ($renderingInstance) {
if($renderingInstance.Datasource -ne $DatasourceId)
{
Write-Host $item.FullPath
Write-Host $renderingInstance.DataSource
Write-Host “Updating Rendering DataSource”
$renderingInstance.Datasource = $DatasourceId
Set-Rendering -Item $item -Instance $renderingInstance
Write-Host “Updated DataSource ID”
Write-Host $renderingInstance.Datasource
}
else
{
Write-Host “Correctly Mapped”
Write-Host $item.FullPath
Write-Host $renderingInstance.DataSource
}
}
}
- Change Child Item Template
$items = Get-ChildItem -Path “master:” -Recurse | Where-Object { $_.TemplateID -eq “{Template ID of the items you wish to change the Template}” }
$templateitemid = “Target Template ID”
$templateitem = Get-Item -Path “master:” -ID $templateitemid
foreach($item in $items)
{
if($item.TemplateID -eq “{Template ID of the items you wish to change the Template}”) //Basically, you don’t need this, because already your list contains only the child items matching this template ID//
{
Set-ItemTemplate -Item $item -TemplateItem $templateitem
}
}
P.S: Set-Template has an optional parameter -FieldsToCopy which can be used to map the Fields of Source Item of Tempalte A to Modified Item of Tempalte B
- Add-Rendering to an Item
$item = Get-Item -Path “master:/sitecore/content/…”
$rendering = Get-Item -Path “master:/sitecore/layout/Renderings/….” | New-Rendering
Add-Rendering -Item $item -Instance $rendering -PlaceHolder “PlaceHolder” -DataSource “Data Source” -FinalLayout
Adding a rendering to a group of items can be done in several ways – if they all belong to the same template we can add the rendering to the Standard Templates, or even if they are from different templates, we can leverage the individual template’s standard template and get the job done.
Imagine a situation where we can’t apply the above two solutions. May be they are from same template but the Data Source to be set for these rendering differs item wise or these renderings are to be added only to a particular sub children of items belonging to a certain template. In those scenarios, the Data Source can be fetched dynamically via PowerShell script based on the requirement and can be passed on to renderings to be added.
- Add/Update Rendering Parameters for all child items
$items = Get-ChildItem -Path “master” -ID “ITEM ID” -Recurse
$renderingItemID = “”
foreach($item in $items)
{
Get-Rendering -Item $item -FinalLayout | Where-Object { $_.ItemID -eq $renderingItemID} |
Set-RenderingParameter – Parameter @{“KEY”=”VALUE”} |
Set-Rendering -Item $item -FinalLayout
Write-Host “Updated Items:” $item.Paths.FullPath
}
If it’s an existing parameter, we can specify the Key and new value. It will overwrite the existing value. If it’s a new Parameter, it will add the parameter to existing rendering parameter list.
Note:
- It’s wise to take a back up of the Content Items, before working on modifying items on a large scale like a package or from a DB end. So that, you can always have an option of reverting back to previous version.