Sitecore Powershell Reporting
The Sitecore PowerShell Extensions (SPE) module has a lot of nice features. One of them is creating reports. You get quite some reports out-of-the-box with the module, but you can also create your own.
I recently noticed however that people are still creating custom pages to create reports for the admins of the customer. Although this gives you a lot of flexibility and perhaps options to include data that resides not in Sitecore this also has some drawbacks compared to creating reports in PowerShell.
The SPE reports are completely integrated in the Sitecore editing environment. This makes it possible to (amongst others):
- use context items: the output in the report can be based upon the item it was requested on
- open items in the editor: directly open the editor from the report
- more future-proof - especially if you would move to a saas solution
Next to that - the SPE module comes with some very handy features like the Show-ListView which gives your admins a nice toolbox without any effort.
But enough about the benefits of SPE - let's dive into the example I wanted to show here.
Redirect module
I assume many Sitecore developers have had the request to add some sort of redirect module, enabling editors to create redirects without intervention of IT-people having to change the rewrite instructions.
There used to be several modules floating around in the Sitecore community - but to be honest none of them was ever really perfect. SXA also has it's own implementation of redirects, and that had a different approach than most of the modules. Instead of having a repository of redirect items and using pipeline code to handle them, it is also an option to place the redirects in the tree where you actually want them.
This brings me to the request that led to this post: creating redirect in a non-SXA XM project in a way that they are easily handled by the admins.
We decided to create a page template with a layout that redirect the page based on some values that can be edited inside the page (eg url, permanent redirect, ... ). You can actually go pretty far in this if you want but as that is not our main focus here let's keep it to that. The focus is here is on answering the question from the Sitecore admins:
"Where are all my redirects?"
Let's answer that question with Sitecore PowerShell. Note that we are using redirects here as an example and this can be done for any kind of data in Sitecore. Also note that out-of-the-box there already is a report to fetch all items based on a template within a folder. But that report is very generic and we wanted a fancy one. Of course, we will copy from this one to give us a head start.
We start with some functions to assist the actual reports.
Sitecore PowerShell Functions
Functions are a way to reuse parts of the code. We will use two functions for our report. The first one is to check whether the item is published to the web database. As many pieces of software, this one is just a copy. But as we in the Sitecore community are honest, we mention our sources. Kudos to Gabriel Streza for this one.
Get-IsPublished
function Get-IsPublished {
[CmdletBinding()]
param(
[Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[Sitecore.Data.Items.Item]$Item
)
$WebDbItem = Get-Item web: -Id $Item.ID
if ($null -ne $WebDbItem) {
return $true
}else{
return $false
}
}
I assume this one is fairly easy and doesn't need more explanation. The second function will fetch the items and show the report. This is actually the core of the whole thing.
Show-RedirectReport
function Show-RedirectReport{
[CmdletBinding()]
param (
[Parameter(Mandatory=$true, Position=0)]
[string]$templateId,
[Parameter(Mandatory=$true, Position=1)]
[string]$path
)
$items = Find-Item -Index sitecore_master_index `
-Criteria @{Filter = "Equals"; Field = "_template"; Value = "$templateId"},
@{Filter = "Equals"; Field = "_language"; Value = "en"},
@{Filter = "StartsWith"; Field = "_fullpath"; Value = "$path" } | Initialize-Item
Import-Function Get-IsPublished
if($items.Count -eq 0) {
Show-Alert "There are no redirects here."
} else {
$props = @{
Title = "Redirect Report"
PageSize = 25
}
$items |
Show-ListView @props -Property @{Label="Name"; Expression={$_.DisplayName} },
@{Label="Updated"; Expression={$_.__Updated} },
@{Label="Updated by"; Expression={[Sitecore.Security.Accounts.User]::FromName($_."__Updated by", $false).Profile.FullName}},
@{Label="Path"; Expression={$_.ItemPath} },
@{Label="Target - Url"; Expression={$link = $_._.RedirectUrl
if ($link.IsInternal) { $link.TargetItem.Paths.Path } else { $link.Url }} },
@{Label="Permanent"; Expression={$_._.Permanent.Checked} },
@{Label="Published"; Expression={Get-IsPublished -Item $_ } }
}
}
We will go a little deeper into this one. It has two parts.
First of all we are fetching items through the master index. The function expects a templateID and a path and we will use those to fetch all items of that template in that path (in English).
If we found some items, we are using Show-ListView to display the report. Most of the fields we are showing are quite common but a few deserve some attenion:
- Updated by: we are using the security account here to fetch the full name of the profile instead of the Sitecore login name as that might be much more readable. Kudos to the one and only Adam Najmanowicz for this one.
- Target: this can be an internal or external link so we use the "._" notation (short for .PSFields) to access the typed field and check what we need to show
- Permanent: again using ._ to handle this as a checkbox
- Published: using our Get-Published function here
The report
Once we have our two functions, the report itself is very easy. We need to collect the parameters to pass to the report function and we should be ok.
$templatePath = "master:\templates\xxx\Shared\Redirect"
$baseTemplate = Get-Item -Path $templatePath
$templateId = $baseTemplate.ID
$path = "/sitecore/content/Sites"
Import-Function Show-RedirectReport
Show-RedirectReport -templateId $templateId -path $path
Close-Window
As this report is intended to be used for one specific template we can hardcode that. We did the same for the base path for now - it's the root path for all content in this case.Location
In our Sitecore PowerShell module we create (or go to) a folder Reports: "/sitecore/system/Modules/PowerShell/Script Library/xxx/Reports". Here we create a PowerShell Script Library that will be the folder in the reporting tools section. In that folder we place our PowerShell Script - "Redirects". That will result as shown here:
The context menu
To add the report to the context menu and use the context item as the start path, we simply add a new script to our library.
$templatePath = "master:\templates\xxx\Shared\Redirect"
$baseTemplate = Get-Item -Path $templatePath
$templateId = $baseTemplate.ID
$contextItem = Get-Item .
$path = $contextItem.Paths.FullPath
Import-Function Show-RedirectReport
Show-RedirectReport -templateId $templateId -path $path
Close-Window
Not many differences compared to what we already had - just the path is now coming from the context item ".".
Location
We are placing the new script in the folder "Content Editor/Context Menu" in our SPE module. But note that in this case we don't only take care of the location as this location will add the script everywhere but we want to limit it a little bit. We can use the Show Rule to define where the script will be shown in the context menu. In our case, we limit it to items of 2 specific templates but you can use any rule here.
This will look like this:
The final result
I want to show a screenshot of the final result as well - especially for those people who are not so familiar with Sitecore PowerShell yet. For others it will look very familiar - but that doesn't make it less nice :)
In conclusion I would remind you once more that if you need to bring reports to your editors or admins, think about Sitecore PowerShell. It is a really cool tool that will bring you the result you need. And on top of that you can find a lot of resources already from Sitecore community people that have shared scripts and/or snippets to give you ideas and help you write your own scripts. And maybe this one extra post helps someone as well.




No comments:
Post a Comment