All Articles

Sitecore Powershell Extensions Example Scripts

Introduction to Sitecore Powershell Extensions

The Sitecore PowerShell Extensions (SPE) module is a Sitecore development accelerator that can drastically increase your productivity and curtail the amount of time it takes to deliver a Sitecore solution.

The module provides a command line (CLI) and a scripting environment (ISE) for automating tasks. SPE works with the Sitecore process, capable of making native calls to the Sitecore API and manipulating files. Running commands and writing scripts follow the standard and well-known Windows PowerShell syntax. Windows PowerShell is a common tool used in IT for desktop and server management, so we decided to stick with that as a framework to build upon.

You can read more about Sitecore Powershell Extensions here.

Directions to use

The scripts that I have posted below can be pasted and directly executed on the Powershell ISE provided by SPE.

Please modify the variables as per your requirement before executing them.

ToArray

This method is the most simple, and the one I often use. As sometimes the result of a certain query/filter can be a single item, I use ToArray to ensure that the result will be an array.

Script:

function ToArray
{
  Begin {$output = @();  }
  Process {  $output += $_; }
  End {   return ,$output;  }
}

Usage:

$AllItems = Get-ChildItem $ParentItem.ID -Language $Language -Recurse | Where-Object { $_.TemplateName -eq $TemplateName } | ToArray
# After the child items are filtered based on the template id,
# There's always a chance that the resulting item may be a single item
# ToArray ensures that the result will always be an array
# We can further write the script assuming $AllItems will be an array

Using a class to create objects with Powershell

As we are very much used to Object-Oriented Programming, we are used to creating classes for every entity we use in our code. When scripting with Powershell, creating classes can make the code more readable and help us write the logic efficiently.

Class Redirection
{
    [string] $From;
    [string] $To;
    Redirection([string] $fromIn, [string] $toIn)
    {
        $this.From = $fromIn.Trim();
        $this.To = $toIn.Trim();
    }
}

Usage:

$item = [Redirection]::new("/from/url", "/to/url")

Read items from a CSV file

The class used in the below example will have to be changed as per your needs.

Script:

Class Redirection
{
    [string] $From;
    [string] $To;
    Redirection([string] $fromIn, [string] $toIn)
    {
        $this.From = $fromIn.Trim();
        $this.To = $toIn.Trim();
    }
}
function Read-ItemsFromCsv
{
    $File = Receive-File $SitecoreTempFolder
    if($File -ne "cancel" -and $File.EndsWith(".csv"))
    {
        $CsvData = Import-Csv $File
        [Redirection[]]$AllItems = @()
        foreach($entry in $CsvData)
        {
            if($entry -ne $null -and $entry.From -ne $null -and $entry.To -ne $null)
            {
                $item = [Redirection]::new($entry.From, $entry.To)
                if($item -ne $null)
                {
                    $AllItems += $item
                }
            }
        }
    }
    Remove-Item $File
    return $AllItems
}

The variable $SitecoreTempFolder used in the above script is a global variable provided by SPE itself, which gives the path to the temp folder of the Sitecore instance.

Usage:

$AllRedirections = Read-ItemsFromCsv

Get or Create an Item of a certain Template under a Parent item

We always have certain items that need to be always created under a specific type of item. For example, we always have the local-data item under every page for an SXA site. This method can be specifically used in these cases.

The Select -First 1 in the script is the Powershell equivalent for the LINQ First(), and the Where-Object is the Powershell equivalent for LINQ Where().

Script:

function GetOrCreate-ItemWithTemplate
{
    Param([Sitecore.Data.Items.Item] $ParentItem,[System.String] $TemplateId, [System.String] $Language, [System.String] $Name, [bool] $CheckForName = $False)
	Process
    {
        if($CheckForName -eq $False)
        {
		    $ItemRequired = Get-ChildItem $ParentItem.ID -Language $Language | Where-Object { $_.TemplateId -eq $TemplateId} | Select -First 1
        }
        else
        {
            $ItemRequired = Get-ChildItem $ParentItem.ID -Language $Language | Where-Object { $_.TemplateId -eq $TemplateId -and $_.Name.Trim() -eq $Name.Trim()} | Select -First 1
        }
        if($ItemRequired -eq $null)
		{
			$ItemRequired = New-Item -Path $ParentItem.Paths.Path -ItemType $TemplateId -Name $Name -Language $Language
		}
    }
    End
    {
        return $ItemRequired
    }
}

Usage:

  1. When the child item is needed, but the name if that item doesn’t matter.

    $RequiredItem = GetOrCreate-ItemWithTemplate -ParentItem $ParentFolderItem -TemplateId $ItemTemplateId -Name $ItemName -Language $Language
  2. When the name of the child item matters.

    $RequiredItem = GetOrCreate-ItemWithTemplate -ParentItem $ParentFolderItem -TemplateId $ItemTemplateId -Name $ItemName -Language $Language -CheckForName $True

Read Items under a Parent Item

This method can be used in cases where you need to recursively select items under a parent folder and filter them based on a template.

Script:

function ToArray
{
  Begin {$output = @();  }
  Process {  $output += $_; }
  End {   return ,$output;  }
}
function Read-ItemsUnderParent
{
    Param([System.String] $ParentItemPath, [System.String] $TemplateName, [System.String] $Language, [System.Boolean] $IncludeParent = $False)
    Begin
    {
        $ParentItem = Get-Item -Path $ParentItemPath -Language $Language
    }
    Process
    {
        $AllItems = Get-ChildItem $ParentItem.ID -Language $Language -recurse | Where-Object { $_.TemplateName -eq $TemplateName} | ToArray
        if($IncludeParent)
        {
            $AllItems += $ParentItem
        }
    }
    End
    {
        return $AllItems
    }
}

Usage:

  1. When you do not want to include the parent item in the selection.

    e.g. Select all Products under a bucket folder.

    $AllProducts = Read-ItemsUnderParent -ParentItemPath $ParentItemPath -TemplateName $TemplateNameOfItems -Language $LanguageOfItem
  2. When you want to include the parent item as well in the selection

    e.g. Select all pages under a Home item, include Home as well as it is a page.

    $AllPages = Read-ItemsUnderParent -ParentItemPath $HomeItemPath -TemplateName $PageTemplateName -Language $LanguageOfItem -IncludeParent $True

Get item with the matching field value from a collection of items

Script:

function Get-ItemWithMatchingField
{
    Param([Sitecore.Data.Items.Item[]] $ItemCollection, [System.String] $FieldName, [System.String] $ValueToMatch)
    Process
    {
        $MatchingItem = $ItemCollection | Where-Object { $_.[$FieldName].Trim() -eq $ValueToMatch.Trim()} | | Select -First 1
    }
    End
    {
        return $MatchingItem
    }
}

Usage:

$RequiredArticle = Get-ItemWithMatchingField -ItemCollection $AllArticles -FieldName "Article Name" -ValueToMatch "My Article"

Updating a Media Field with Powershell

Script:

function Update-MediaField
{
    Param([Sitecore.Data.Items.Item] $Item, [System.String] $FieldName, [System.String] $TargetId)
    Process
    {
        $Item.Editing.BeginEdit()
        [Sitecore.Data.Fields.ImageField]$field = $Item.Fields[$FieldName]
        $field.Alt = $Item.Name
        $field.MediaID = $TargetId
        $Item.Editing.EndEdit()
    }
}

Usage:

Update-MediaField -Item $ItemToUpdate -FieldName $FieldToUpdate -TargetId $MediaItem.ID

Add rendering to a page

Script:

function Add-RenderingToPage
{
    Param([Sitecore.Data.Items.Item] $PageItem,[System.String] $RenderingPath, [System.String] $Placeholder, [Sitecore.Data.Items.Item] $DataSourceItem = $null, [System.String] $Database = "master")
	Process
    {
        $RenderingItem = Get-Item -Database $Database -Path $RenderingPath | New-Rendering -Placeholder $Placeholder
		if($DataSourceItem -eq $null)
		{
			Add-Rendering -Item $PageItem -PlaceHolder $Placeholder -Instance $RenderingItem -DataSource $DataSourceItem.Paths.Path
		}
		else
		{
			Add-Rendering -Item $PageItem -PlaceHolder $Placeholder -Instance $RenderingItem -DataSource ""
		}
    }
}

Usage:

Add-RenderingToPage -PageItem $CurrentPage -RenderingPath $MyRenderingPath -Placeholder "main" -DataSourceItem $MyDataSourceItem

I will keep adding more and more scripts as and when I can to this post. Feel free to bookmark this page and refer as needed.

Also, do let me know in the comments if you feel a particular use case is missing and you need it in the article.

Feedback and Suggestions welcome!

Happy Sitecoring!!