When looking at the broken links report or broken links in the bumper, sometimes it will reference a broken link in the Final Renderings. But no info is available to know which rendering is doing it. Placeholder settings, when missing show a different icon and if the rendering is completely missing from Sitecore, a bid red X is showing. But being able to identify a rendering with a bad datasource would be helpful.

Has anyone found a quick way to identify bad renderings?

enter image description here

  • Have you tried the broken links report with SPE? Apr 21, 2019 at 18:54
  • No. But will that tell me the specific rendering name/id?
    – Chris Auer
    Apr 21, 2019 at 19:24

1 Answer 1


I had to make a modification to the existing Broken Links report included with SPE to show the broken renderings.

        Lists the items with broken links searching all or the latest version in the current language.

        Adam Najmanowicz, Michael West, Daniel Scherrer
        Adapted from the Advanced System Reporter module & Daniel Scherrer's external links checker: 

$database = "master"
$root = Get-Item -Path (@{$true="$($database):\content\home"; $false="$($database):\content"}[(Test-Path -Path "$($database):\content\home")])
$linksToCheck =  @("internal")
$linkTypes = [ordered]@{"Internal Links"="internal";"External Links (General Link only)"="external"};

$versionOptions = [ordered]@{

$props = @{
    Parameters = @(
        @{Name="root"; Title="Choose the report root"; Tooltip="Only items in this branch will be returned."; Columns=9},
        @{Name="searchVersion"; Value="1"; Title="Version"; Options=$versionOptions; Tooltip="Choose a version."; Columns="3"; Placeholder="All"},
        @{Name="linksToCheck"; Title="Link types to check"; Options=$linkTypes; Tooltip="which link types you want to check"; Editor="checklist"} 
    Title = "Broken Links Report"
    Description = "Choose the criteria for the report."
    Width = 550
    Height = 300
    ShowHints = $true
    Icon = [regex]::Replace($PSScript.Appearance.Icon, "Office", "OfficeWhite", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)

$result = Read-Variable @props

if($result -eq "cancel"){

filter HasBrokenLink {


    if(!$Item) { return }
    if($linksToCheck.Contains("internal")) {
        $brokenLinks = $item.Links.GetBrokenLinks($IncludeAllVersions)
        if($brokenlinks -ne $null -and $brokenlinks.Length -gt 0) {
            $finalRenderings = Get-Rendering -Item $Item -FinalLayout
            $sharedRenderings = Get-Rendering -Item $Item
            $uniqueIdLookup = New-Object System.Collections.Generic.HashSet[string]
            foreach($brokenLink in $brokenLinks) {
                if([ID]::IsNullOrEmpty($brokenLink.SourceFieldID)) { continue }
                $fieldItem = Get-Item -Path "$($Item.Database.Name):\" -ID $brokenLink.SourceFieldID
                if(!$fieldItem) { continue }
                $renderings = & {
                    switch($fieldItem.ID) {
                        "{04BF00DB-F5FB-41F7-8AB7-22408372A981}" {
                        default {
                $brokenRendering = $renderings | Where-Object { $_.Datasource -eq $brokenLink.TargetPath -and !$uniqueIdLookup.Contains($_.UniqueId) } | Select-Object -First 1
                if(!$brokenRendering) { continue }
                $uniqueIdLookup.Add($brokenRendering.UniqueId) > $null
                $brokenRenderingItem = Get-Item -Path "master:" -ID $brokenRendering.ItemId
                $brokenItem = [pscustomobject]@{
                    "__Updated by"=$Item."__Updated by"
                    "Link Field"=$fieldItem.Name
                    "Rendering" = $brokenRenderingItem.Name
                    "Target Path"=$brokenLink.TargetPath
                    "Status Code"="Missing Target Item"
                    "Link Type" = "Internal"



            $allItems = Get-Item "$($item.Database.Name):" -Version * -Language * -Id $item.Id
        } else {
            $allItems = @(Get-Item "$($item.Database.Name):" -Language * -Id $item.Id)
        foreach($checkedItem in $allItems){
            foreach($field in $checkedItem.Fields) {
                if ($field.Type -eq 'General Link' -and $field.Value -like '*linktype="external"*') { 
                    $found = $field.Value -match '.*url="(.*?)".*'
                    if($found) {
                        $url = $matches[1]

                        $response = Invoke-WebRequest -Uri $url -UseBasicParsing -Method head
                    catch {
                        $statuscode = $_.Exception.Response.StatusCode.Value__

                        if(!$statuscode) {
                            $statuscode = "Not reachable"

                        $brokenItem = [pscustomobject]@{
                            "__Updated by"=$checkedItem."__Updated by"
                            "Link Field"=$field.Name
                            "Target Path"=$url
                            "Status Code"=$statuscode
                            "Link Type"="External"


$items = @($root) + @(($root.Axes.GetDescendants() | Initialize-Item)) | HasBrokenLink -IncludeAllVersions (!$searchVersion)

if($items.Count -eq 0){
    Show-Alert "There are no items found which have broken links in the current language."
} else {
    $props = @{
        Title = "Broken Links Report"
        InfoTitle = "$($items.Count) items with broken links found!"
        InfoDescription = "The report checked for $($linksToCheck -join ' & ') links in $(@('all versions','latest versions')[[byte]($searchVersion='1')]) of items."
        MissingDataMessage = "There are no items found which have broken links in the current language."
        PageSize = 25
        ViewName = "BrokenLinks"
        Property = @(
            "Icon","Status Code", 
            @{Label="Name"; Expression={$_.DisplayName} }, 
            @{Label="Item Path"; Expression={$_.ItemPath} },"Link Field", "Rendering","Target Path",
            "Link Type",
            @{Label="Updated"; Expression={$_.__Updated} },
            @{Label="Updated by"; Expression={$_."__Updated by"} }

    $items | Show-ListView @props

This will make a nice addition to 5.1 (whenever that comes out). You can see below that the rendering in question is now included. You could take the script further and show which placeholder holds the rendering.

Example Report

  • Awesome! Nice work Mike. What I will try to do is add it as a right click on an item that will scan just that item. Then we can easily find broken renderings on the site. Thanks again.
    – Chris Auer
    Apr 22, 2019 at 17:53
  • Nice work. In a project with an older version of SPE I made this a context menu script and tweaked the script to set the root to the current item like so: $root = Get-Item . Apr 23, 2020 at 11:07

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.