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?
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
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 }
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
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.
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...