11

The title pretty much says it all - I've looked at the docs but I just keep finding Get-Item and Get-ItemTempate.

Lets say I have a template with id 123456, I want to get all items that are using this template. How would I do that?

2
  • How would you do that in C#? Commented Nov 26, 2018 at 15:25
  • Something like allItems.Where(p => p.TemplateIdList.Contains("123456")); Let me see if I can powershell that! - Disclaimer - New to Sitecore so I don't know what exists and what doesn't...
    – Percy
    Commented Nov 26, 2018 at 15:33

6 Answers 6

11

This should do it for you.

$defaultPath = "/sitecore/content"
[Sitecore.Data.ID]$articleId = "{03360FC1-B4C0-4770-9E1D-79E8317B74DD}"

$articles = Find-Item -Index sitecore_master_index `
   -Where 'TemplateId = @0 and Path.StartsWith(@1)' `
   -WhereValues $articleId, $defaultPath | Initialize-Item

Another way using template name and Criteria.

$articles = Find-Item `
   -Index sitecore_master_index `
   -Criteria @{Filter = "Equals"; Field = "_templatename"; Value = "Article"},
   @{Filter = "Equals"; Field = "_language"; Value = "en"},
   @{Filter = "StartsWith"; Field = "_fullpath"; Value = "/sitecore/content" } 
4
  • If I do a Write-Host $_.FullPath on everything in $articles, then I get quite a log of duplicates. Any idea why this would happen?
    – Percy
    Commented Nov 26, 2018 at 16:52
  • (using the first example btw)
    – Percy
    Commented Nov 26, 2018 at 17:08
  • multiple languages? This is is reading directly from the index, so we have to know why there are multiple items in your index.
    – Chris Auer
    Commented Nov 26, 2018 at 17:18
  • 1
    Ah potentially - I'll investigate if that is the case. Thanks
    – Percy
    Commented Nov 26, 2018 at 17:18
20

There is a report included with SPE called Items with Template that can provide you with this information. This report scans a tree and checks for inheritance at any level. Slow because it has to look at every item. Incomplete because it only looks at the tree specified.

Sample Report Dialog

I would recommend you use the Get-ItemReferrer command. This is based on the Link Database and should be extremely fast; items that in no way are related are never requested. Be sure the Link Db is up-to-date before running.

A similar question was asked here.

Find related items

Example: The following returns all items referring to a given template.

$sampleItemTemplateId = "{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}"
$sampleItemTemplateItem = Get-Item -Path "master:" -ID $sampleItemTemplateId

Get-ItemReferrer -Item $sampleItemTemplateItem

As you can see below, all referrers are returned. You can then filter out with Where-Object if you want to exclude content, media, templates, etc.

enter image description here

Find related items at any level of inheritance

Example: The following returns all items referring to a given template that inherit that template. Demonstrates the use of the trampoline technique to reduce call depth. There are checks to ensure that the item exists and no duplicates are returned.

function Get-ItemBasedOnTemplate {
    param(
        [string]$TemplateId
    )

    $queue = New-Object System.Collections.Queue
    $processedLookup = New-Object System.Collections.Generic.HashSet[string]
    if(-not(Test-Path -Path "master:$($TemplateId)")) { return }
    $processedLookup.Add($TemplateId) > $null  
    Get-ItemReferrer -Id $TemplateId -ItemLink | 
        Where-Object { $_.SourceItemID } | 
        ForEach-Object { $queue.Enqueue($_.SourceItemID) }

    $database = Get-Database -Name "master"
    while($queue.Count -and ($referrerId = $queue.Dequeue())) {
        if($processedLookup.Contains($referrerId)) { continue }
        $processedLookup.Add($referrerId) > $null
        $referrer = $database.GetItem($referrerId)
        if(!$referrer) { continue }
        if($referrer.Paths.FullPath.StartsWith("/sitecore/templates")) { 
            if($referrer.Name -eq "__Standard values") { continue }
            foreach($referrerItemLink in Get-ItemReferrer -Id $referrerId -ItemLink | Where-Object { $_.SourceItemID }) {
                $queue.Enqueue($referrerItemLink.SourceItemID)
            }
            $itemTemplate = [Sitecore.Data.Managers.TemplateManager]::GetTemplate($referrerId, $database)
        } else {
            $itemTemplate = [Sitecore.Data.Managers.TemplateManager]::GetTemplate($referrer)
        }
        
        if ($itemTemplate -and $itemTemplate.DescendsFromOrEquals($TemplateId)) {
            $referrer
        }
    }
}
$baseTemplateId = "{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}"
Get-ItemBasedOnTemplate -TemplateId $baseTemplateId

Demo

The following demonstrates three base templates: Base Template -> Base Template 1 -> Base Template 2

Query base template

Interesting discovery. Switched from Get-Item to $db.GetItem() and the results are considerably faster; SPE wraps objects returned Get-Item and Get-ChildItem with additional properties.

$baseTemplateId = "{3F8A6A5D-7B1A-4566-8CD4-0A50F3030BD8}"
$watch = [System.Diagnostics.Stopwatch]::StartNew()
$itemCount = Get-ItemBasedOnTemplate -TemplateId $baseTemplateId | 
    Measure-Object | Select-Object -Expand Count
$watch.Stop()
$time = $watch.ElapsedMilliseconds / 1000
Write-Host "Discovered and returned $($itemCount) items in $($time) seconds"

# Discovered and returned 1307 items in 0.527 seconds
1
  • Nice one Mike. Didn't know that existed.
    – Chris Auer
    Commented Nov 26, 2018 at 17:12
3

I have done this using the below script. The idea is to go through all the child items of a node to check if the template id of the item matches with template id we are looking for or inherits from it-

$TemplateId = [Sitecore.Data.ID]::Parse("{<your templateId here>}");
$database = "master"
$contentRoot =  Get-Item -Path "/sitecore/content/<your site path here>"
filter Where-InheritsTemplate {
    param(
        [Parameter(Mandatory = $true,ValueFromPipeline = $true)]
        [Sitecore.Data.Items.Item]$item
    )
    if ($item) {
        $itemTemplate = [Sitecore.Data.Managers.TemplateManager]::GetTemplate($item)
        if ($itemTemplate -ne $null -and $itemTemplate.DescendsFromOrEquals($TemplateId)) {
            $Item
        }
    }
}
Get-ChildItem -Path $contentRoot.FullPath | Where-InheritsTemplate
1

I had an additional requirement where addition to finding a specific template, check if the particular field is not null or empty

I extended @vadim Birkos's script and updated a little bit as $_.Fields["__template"].Value -eq $templateId wasn't working for me so I used $_.TemplateId -eq $templateId

$templateId = "{6F6A4612-5750-46CE-97CE-EBDC599FE480}" # Replace with your template ID

# Get all items in the content tree
$items = Get-ChildItem -Path "master:<your content tree>" -Recurse


# Filter the items by template
$itemsUsingTemplate = $items | Where-Object { $_.TemplateId -eq $templateId  -and !([string]::IsNullOrEmpty($_.Fields["SitecoreField"].Value))}

# Output the item paths
$itemsUsingTemplate | ForEach-Object { Write-Host $_.Paths.Path }
2
  • thank you! Updated part that didn't work for you Commented Apr 11, 2023 at 10:42
  • 1
    Your welcome :) Commented Apr 12, 2023 at 4:34
0

This will work.

$rootItemId = "{rootItemId }"

$rootItem = Get-Item -Path "master:" -ID $rootItemId

$templateId = "{templateId }"

$query = "fast:$($rootItem.ItemPath)//*[@@templateid='$($templateId)']"

Get-Item -Path "master:" -Query "fast:/sitecore/content/<your site path here>//*[@@templateid='{templateid}']" | Format-Table -Property DisplayName, Id
0

To get all items that are using a specific template in Sitecore using PowerShell, you can use the Get-ChildItem cmdlet to retrieve all items in the content tree, and then filter the items by checking if they have a __template field with the ID of the template.

Here's some example PowerShell code that demonstrates how to do this:


$templateId = "{12345678-1234-1234-1234-123456789012}" # Replace with your template ID

# Get all items in the content tree
$items = Get-ChildItem -Path "master:\content\home" -Recurse

# Filter the items by template
$itemsUsingTemplate = $items | Where-Object { $_.TemplateId -eq $templateId  -and !([string]::IsNullOrEmpty($_.Fields["SitecoreField"].Value))}

# Output the item paths
$itemsUsingTemplate | ForEach-Object { Write-Host $_.Paths.Path }

In this example, we're getting all items in the content tree starting from the home item, and then filtering them by checking if they have a __template field with the ID of the template. The filtered items are stored in the $itemsUsingTemplate variable, and then their paths are outputted using the Write-Host cmdlet. You can replace the template ID and the starting path with your own values.

[Updated] Updated because part with condition didn't work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.