Create Better Looking Reports Using Sitecore PowerShell

Example Subheading

February 10, 2022

By David Austin

More than a few times now I've been asked to create a report to display a set of information on a set of data in Sitecore. This might have been showing a list of articles that meet specific criteria, or showing when things were last modified. The list is varied. And while there are out-of-the-box reports that do quite a number of the things we need, I wanted to do something a bit more customized.

The Problem

The challenge this time was to generate a report of a list of articles that had dates between specific dates.

Seems easy enough and it is, but I wanted to have that report look a lot more professional than just listing things out in the PowerShell ISE. I wanted to have a bit of an interface that allowed people to select two dates properly before listing the data out and not have to update a script each time.

The Solution

The first thing that needed to happen was to prompt the user for two sets of dates.

Building the Interface

In PowerShell it's remarkably simple to build an interface that allows for user input. The following bit of code is able to produce this great looking interface to the user.

PowerShell report filter modal

$settings = @{
    Title = "Report Filter"
    OkButtonName = "Proceed"
    CancelButtonName = "Abort"
    Description = "Filter the results for items between the specified dates"
    Parameters = @{
        Name = "selectedAfterDate"
        Value = [System.DateTime]::Now
        Title = "Select the dates for which articles match"
        Tooltip = "Filter the results for items updated after the specified date"
        Editor = "date time"
    }, @{
        Name = "selectedBeforeDate"
        Value = [System.DateTime]::Now
        Title = "Date"
        Tooltip = "Filter the results for items updated before the specified date"
        Editor = "date time"
    }
    Icon = [regex]::Replace($PSScript.Appearance.Icon, "Office", "OfficeWhite", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
    ShowHints = $true
}
$result = Read-Variable @settings
if($result -ne "ok") {
    Exit
}

The Query

With the largest hurdle complete, now all I needed to do was to take those inputs and inject them into a query that delivered me the information I was after.

Now your query can be as complicated or as simple as it needs to be. For me, the following performed the best. Take note at the second line where I use the parameter names from above and cast them as DateTime to make the comparison. i.e. $selectedAfterDate and $selectedBeforeDate.

$articlesContainer = Get-Item -Path "master:\sitecore\content\common\articles"
$items = $articlesContainer.Axes.GetDescendants() |
        Where-Object { $_.Fields["Date"] -ne $null -and [Sitecore.DateUtil]::IsoDateToDateTime($_.Fields["Date"]) -ge [DateTime]$selectedAfterDate -and [Sitecore.DateUtil]::IsoDateToDateTime($_.Fields["Date"]) -le [DateTime]$selectedBeforeDate}

With the items captured, now I just had to display them in a meaniful and good-looking way. For that, we turn to Show-ListView.

The Results

Displaying the results in a good-looking report, one that can then be exported and used in whatever way the user wants is something I love about the OOTB reports. The majority of them use Show-ListView in some way or another.

First step is to create the report properties.

$reportProps = @{
    Title = "Articles in Date Range"
    InfoTitle = "Articles in Date Range"
    InfoDescription = "Articles found  after $($selectedAfterDate) and before $($selectedBeforeDate)"
    Property = @(@{ Label="Title"; Expression={$_.Fields["Title"]}; },
                  @{ Label="URL"; Expression={Get-ItemUrl -SiteContext $siteContext -Item $_};},
                  @{ Label="Authors"; Expression={Get-Authors -ListOfGuids $_.Fields["Authors"]}; } ,
                  @{ Label="Date"; Expression={[datetime]::ParseExact($_.Fields["Date"],'yyyyMMddTHHmmssZ',$null)}; } ,
                  "ID")

So as you can see above, we have all the fields that make up the report view itself along with the Property field that lists out all the columns in the report.

Each "property" is made up of the Label and an Expression which displays the value. You can, as you can see, call functions in that Expression field to improve the quality of the data. In our case, the authors of the article were from a multi-list so I had to extract their names and display them as comma-delimited.

If you're curious, I've added those function calls below.

function Get-ItemUrl {
    param(
        [item]$Item,
        [Sitecore.Sites.SiteContext]$SiteContext
    )
    $result = New-UsingBlock(New-Object Sitecore.Sites.SiteContextSwitcher $siteContext) {
        New-UsingBlock(New-Object Sitecore.Data.DatabaseSwitcher $item.Database) {
            [Sitecore.Links.LinkManager]::GetItemUrl($item)
        }
    }
    $result[0][0].Replace("://", "https://").Replace("cm.abccompany.com/en/sitecore/content/common/articles", "www.abccompany.com/articles")
}

function Get-Authors { param( [String]$ListOfGuids ) [String[]]$authorNames = @() [String[]]$authorGuids = $ListOfGuids -split "|:" foreach($x in $authorGuids) { if ($x -ne ""){ $item = Get-Item -Path "master:" -ID $x $firstName = $item.Fields["First Name"] $lastName = $item.Fields["Last Name"] $y = "$firstName $lastName" $authorNames += $y } } $result = $authorNames -join '', ' $result }

Using Show-ListView, now only does the user have the ability to export in a variety of formats, but they can also sort the data by the appropriate column. It's just handy all around. Your clients will appreciate it.

Articles in data range modal in Sitecore

Image of Fishtank employee David Austin

David Austin

Development Team Lead | Sitecore Technology MVP x 3

David is a decorated Development Team Lead with Sitecore Technology MVP and Coveo MVP awards, as well as Sitecore CDP & Personalize Certified. He's worked in IT for 25 years; everything ranging from Developer to Business Analyst to Group Lead helping manage everything from Intranet and Internet sites to facility management and application support. David is a dedicated family man who loves to spend time with his girls. He's also an avid photographer and loves to explore new places.