How to Find Unused Sitecore Media Referrers Using PowerShell
In managing Sitecore, it's crucial to maintain smooth performance by keeping track of how content pieces connect. One task often overlooked is finding and fixing unused links connections between items that are no longer needed. These unnecessary links can clutter up your system and slow down operations over time.
With PowerShell, you can automate the process of identifying and handling these unused links across your Sitecore setup. Using scripts like Get-ItemNameById and Process-ItemReferrers, you can easily check how items are linked across different languages and templates. This helps you pinpoint and remove unused links efficiently.
Cleaning up these unused links can significantly improve your Sitecore site's speed and efficiency. This blog explores straightforward PowerShell techniques aimed at enhancing Sitecore performance by effectively identifying and managing unused links.
领英推荐
# Set the buffer size to 300 characters wide and 3000 lines high
$host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size(300, 3000)
# Function to resolve field value to item name
function Get-ItemNameById($id) {
if ($id -ne $null -and $id -ne "*") {
$item = Get-Item -Path master:\ -ID $id
if ($item -ne $null) {
return $item.Name
}
}
return "N/A"
}
# Function to process item referrers for specific language versions
function Process-ItemReferrers($items) {
$results = @()
$includedLanguages = @("en", "fr", "es-ES") # Add more languages here with their language codes
foreach ($item in $items) {
if ($item -ne $null) {
# Iterate through all language versions of the item
foreach ($language in $item.Languages) {
if ($includedLanguages -contains $language.Name) {
$itemInLanguage = $item.Database.GetItem($item.ID, $language)
if ($itemInLanguage -ne $null) {
# Get the updated date of the item
$itemUpdatedDate = $itemInLanguage.Fields["_Updated"].Value
# Get item referrers
$itemReferrers = Get-ItemReferrer -Item $itemInLanguage -ItemLink
if ($itemReferrers -ne $null -and $itemReferrers.Count -gt 0) {
foreach ($referrer in $itemReferrers) {
if ($referrer -ne $null) {
# Get the linked item by its ID
$linkedItem = $masterDatabase.GetItem($referrer.SourceItemID, $language)
if ($linkedItem -ne $null) {
# Get the latest version of the linked item
$latestVersion = $linkedItem.Versions.GetLatestVersion()
if ($latestVersion -ne $null) {
# Retrieve the required fields from the latest version of the linked item
$linkedItemWorkflowStateId = $latestVersion.Fields["Workflow state"].Value
# Resolve IDs to names
$linkedItemWorkflowState = Get-ItemNameById $linkedItemWorkflowStateId
# Skip the referrer if any of the conditions are met
if ($linkedItemWorkflowState -eq "Approved" -or $latestVersion.Paths.FullPath.StartsWith("/sitecore/templates") -or $linkedItemNeverPublish -eq "1" -or $latestVersion.Paths.FullPath.StartsWith("/sitecore/layout") -or $latestVersion.Paths.FullPath.StartsWith("/sitecore/system")) {
continue
}
# Collect the required information
$results += [PSCustomObject]@{
ItemPath = $itemInLanguage.Paths.FullPath
ItemTemplate = $itemInLanguage.TemplateName
ItemUpdatedDate = $itemUpdatedDate
ItemLanguage = $itemInLanguage.Language.Name
LinkedItemPath = $latestVersion.Paths.FullPath
LinkedItemTemplate = $latestVersion.TemplateName
LinkedItemWorkflow = $linkedItemWorkflowState
LinkedItemLanguage = $latestVersion.Language.Name
}
} else {
# Collect N/A values if the linked item is not found
$results += [PSCustomObject]@{
ItemPath = $itemInLanguage.Paths.FullPath
ItemTemplate = $itemInLanguage.TemplateName
ItemUpdatedDate = $itemUpdatedDate
ItemLanguage = $itemInLanguage.Language.Name
LinkedItemPath = "N/A"
LinkedItemTemplate = "N/A"
LinkedItemWorkflow = "N/A"
LinkedItemLanguage = "N/A"
}
}
}
}
}
} else {
# Collect N/A values if no links are found
$results += [PSCustomObject]@{
ItemPath = $itemInLanguage.Paths.FullPath
ItemTemplate = $itemInLanguage.TemplateName
ItemUpdatedDate = $itemUpdatedDate
ItemLanguage = $itemInLanguage.Language.Name
LinkedItemPath = "N/A"
LinkedItemTemplate = "N/A"
LinkedItemWorkflow = "N/A"
LinkedItemLanguage = "N/A"
}
}
}
}
}
}
}
return $results
}
# Function to process items up to 4 levels deep recursively
function Process-ItemsUpToFourLevels($items, $level) {
$allResults = @()
$batchSize = 100
for ($i = 0; $i -lt $items.Count; $i += $batchSize) {
$batch = $items[$i..[math]::Min($i + $batchSize - 1, $items.Count - 1)]
$results = Process-ItemReferrers $batch
$allResults += $results
}
# Process next level items if level < 4
if ($level -lt 4) {
$nextLevel = $level + 1
foreach ($item in $items) {
$nextLevelQuery = $item.Paths.Path + "/*"
$nextLevelItems = $masterDatabase.SelectItems($nextLevelQuery)
if ($nextLevelItems -ne $null) {
$allResults += Process-ItemsUpToFourLevels $nextLevelItems $nextLevel # Recursively process next level items
}
}
}
return $allResults
}
# Output the header
Write-Output "Count, Item Path, Item Template, Item LastModified Date, Item Language, LinkedItem Path, LinkedItem Template, LinkedItem Workflow, LinkedItem Language"
# Get the master database
$masterDatabase = [Sitecore.Configuration.Factory]::GetDatabase("master")
# Use Sitecore Query to get all items from the specified path
$rootQuery = "/sitecore/media library/**"
$rootItems = $masterDatabase.SelectItems($rootQuery)
# Initialize the counter
$count = 0
# Process items recursively up to 4 levels deep
$rootResults = Process-ItemsUpToFourLevels $rootItems 1
foreach ($result in $rootResults) {
$count++
$output = "$count, $($result.ItemPath),$($result.ItemTemplate),$($result.ItemUpdatedDate),$($result.ItemLanguage),$($result.LinkedItemPath),$($result.LinkedItemTemplate),$($result.LinkedItemWorkflow),$($result.LinkedItemLanguage)"
$output | Out-String -Width 4096 | Write-Output # Output results formatted to fit 4096 character width
}
# Output completion message
Write-Host "Completed"
Stay tuned for more insights and practical tips on maximizing your Sitecore environment's performance and scalability.
Hope this works for you. Thankyou.