Let’s be honest here: projects tend to get messy pretty fast. When you’re running multiple sites on the same codebase, keeping track of which renderings are used where can be a real challenge, especially since they all live on the same shared platform. Staying on top of documentation requires serious endurance. And let's face it, most developers aren’t exactly thrilled about writing documentation. Luckily, with tools like AI, this task is becoming much easier :)
To leverage AI effectively, you first need solid data. That’s why I created a PowerShell script that scans your master database, identifies all your sites, pulls all the renderings per site (from both final and shared layouts), and produces a clean JSON report. No gimmicks, just straightforward, useful information — exactly what AI needs to transform the data into a clear and organised table.
Before diving into the technical details, here’s why this matters — whether you’re a Product Owner, Content Editor, or Developer.
Why should it matter to you?
Product Owners: You want to be in control. Having a clear overview of which components run where makes it easier to estimate the risk when changing a component and to make smarter decisions around releases.
Content Editors: This info might not affect your day-to-day work directly, but it can be useful during testing to understand which parts of a site might be impacted by changes.
Developers: You want a comprehensive overview so you can accurately evaluate the risk of your changes and know exactly where and how to test them.
This script puts that map in your hands.
What the Powershell script does
Here’s how it works in a nutshell:
- Switches to the master database — because that’s where all your layout and rendering info lives
- Recursively searches under /sitecore/content for all your site roots, skipping irrelevant system folders
- For each site, it grabs every page and pulls all renderings assigned to the default device, from both shared layout* and final layout**
- Collects all unique rendering IDs, then looks up their names so you get something readable
- Outputs everything as clean, nicely formatted JSON — easy to consume, share, or feed into AI tools for further analysis.
- Save the output into a JSON file for further use
# —————————————————————————————— # 1a) Switch to the master DB Set-Location master: # 1b) Define Dutch language object (adjust language code if needed) $language = [Sitecore.Globalization.Language]::Parse("nl-NL") # —————————————————————————————— # 2) Recursive finder for “site roots”, skipping “Experience platform websites” function Get-SiteRoots { param([Parameter(Mandatory=$true)][Sitecore.Data.Items.Item]$Parent) if($Parent.TemplateName -eq 'Branch') { return } # Cache children once $children = $Parent.GetChildren() # If any child has a __Renderings field with a value, this is a site root if ($children | Where-Object { $_.Fields['__Renderings'] -and $_.Fields['__Renderings'].Value }) { # Output this item and stop recursion here Write-Output $Parent return } # Otherwise, recurse into children foreach ($child in $children) { Get-SiteRoots -Parent $child } } # —————————————————————————————— # 3) Discover all site roots under /sitecore/content $rootContent = Get-Item "master:/sitecore/content" $siteRoots = @(Get-SiteRoots -Parent $rootContent) | Sort-Object -Property Name # —————————————————————————————— # 4) Prepare device & master DB API $device = Get-LayoutDevice -Default $masterDb = [Sitecore.Configuration.Factory]::GetDatabase("master") # —————————————————————————————— # 5) For each site root, collect unique rendering names $results = @() foreach ($siteRoot in $siteRoots) { $uids = New-Object System.Collections.Generic.HashSet[string] $pages = ,$siteRoot + $siteRoot.Axes.GetDescendants() foreach ($page in $pages) { # Get Dutch language version of the page $dutchPage = $page.Database.GetItem($page.ID, $language) $renderings = @(Get-Rendering -Item $dutchPage -Device $device) + @(Get-Rendering -Item $dutchPage -Device $device -FinalLayout) foreach ($r in $renderings) { if ($r.ItemID) { $uids.Add($r.ItemID.ToString()) | Out-Null } } } $names = $uids | ForEach-Object { $item = $masterDb.GetItem([Sitecore.Data.ID]::Parse($_)) if ($item) { $item.Name } } | Sort-Object -Property Name $results += [PSCustomObject]@{ SiteRoot = $siteRoot.Name Renderings = $names } } # —————————————————————————————— # 6) Emit perfectly formatted JSON via parse→serialize trick $results | ConvertTo-Json -Depth 5 | # serialize ConvertFrom-Json | # parse back into objects ConvertTo-Json -Depth 5 | # re-serialize with proper indentation Out-Host # push to the console
How to leverage AI
- Rows: unique SiteRoot values
- Columns: unique RenderingItemName values
- Cell values: a checkmark (✓) if the SiteRoot uses that rendering, else empty
- Reads the JSON file
- Extracts all unique SiteRoot and RenderingItemName pairs
- Builds the presence matrix as described
- Saves the matrix as an Excel file named SiteRoot_Renderings_Matrix.xlsx
- Provides the path to the saved Excel file so I can download it
The output will look something like this: