Public/Get-NSPMDECandidateApp.ps1

function Get-NSPMDECandidateApp {
    <#
    .SYNOPSIS
        Collapses crash events (Get-NSPMDECrashEvent) into one row per executable: how often it
        failed, where it lives, on which computers, first and last seen, exception codes.
 
    .PARAMETER InputObject
        Records from Get-NSPMDECrashEvent (pipeline).
 
    .PARAMETER ProcessName
        Keep only these executables (e.g. the app the client complains about). Case-insensitive.
 
    .EXAMPLE
        Get-NSPMDECrashEvent -Days 30 | Get-NSPMDECandidateApp
 
    .EXAMPLE
        Get-NSPMDECrashEvent | Get-NSPMDECandidateApp -ProcessName 'pvxwin64.exe'
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline)][Alias('Event')][AllowNull()][object[]]$InputObject,
        [string[]]$ProcessName = @()
    )
    begin { $all = New-Object Collections.Generic.List[object] }
    process { foreach ($e in $InputObject) { if ($e) { $all.Add($e) } } }
    end {
        # .ToArray(), not @($all): pwsh 7.6 throws "Argument types do not match" on @() of a List
        # made with New-Object.
        $kept = if ($ProcessName) { @($all | Where-Object { $ProcessName -contains $_.ExeName }) } else { $all.ToArray() }
        $kept | Group-Object ExeName | ForEach-Object {
            $g = $_.Group
            [pscustomobject][ordered]@{
                PSTypeName     = 'NSP.MDE.CandidateApp'
                ExeName        = $_.Name
                Hits           = $_.Count
                ExePaths       = @($g.ExePath | Where-Object { $_ } | Sort-Object -Unique)
                Computers      = @($g.Computer | Where-Object { $_ } | Sort-Object -Unique)
                FirstSeen      = ($g.TimeCreated | Measure-Object -Minimum).Minimum
                LastSeen       = ($g.TimeCreated | Measure-Object -Maximum).Maximum
                ExceptionCodes = @($g.ExceptionCode | Where-Object { $_ } | Sort-Object -Unique)
                EventIds       = @($g.EventId | Sort-Object -Unique)
            }
        } | Sort-Object Hits -Descending
    }
}