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?
Sitecore Stack Exchange is a question and answer site for developers and end users of the Sitecore CMS and multichannel marketing software. It only takes a minute to sign up.
Sign up to join this communityThe 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?
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" }
Write-Host $_.FullPath
on everything in $articles
, then I get quite a log of duplicates. Any idea why this would happen?
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.
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.
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.
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
The following demonstrates three base templates:
Base Template -> Base Template 1 -> Base Template 2
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
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
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...