Public/Get-NSPNpsLog.ps1

function Get-NSPNpsLog {
    <#
    .SYNOPSIS
        NPS RADIUS log entries as objects (the database-compatible IN*.log format, the NPS default):
        decoded packet type, authentication type, reason code and policy names, with the raw row kept
        in _Raw.
    .DESCRIPTION
        The parser behind NPS Manager's Read Logs view. With no -Path it reads the most recently
        written IN*.log in the log folder ias.xml configures. -UserName keeps whole request/decision
        groups, not just the rows that carry the name - NPS writes UserName only on the Access-Request
        half of an attempt. For the older IAS or ODBC log formats, use the NPSLogFile module from the
        PowerShell Gallery.
    .PARAMETER Path
        Log file(s). Default: the newest IN*.log in the configured log folder.
    .PARAMETER UserName
        Only attempts by this user (wildcards allowed; matched on UserName and UserFQDN).
    .PARAMETER PacketType
        Only these packet types, e.g. Access-Reject.
    .PARAMETER IASConfigPath
        ias.xml, for the log folder. Default: %SystemRoot%\System32\ias\ias.xml.
    .EXAMPLE
        Get-NSPNpsLog -UserName '*jdoe*' | Format-Table RecordTime, PacketType, ReasonCode, PolicyName
    .EXAMPLE
        Get-ChildItem C:\Windows\System32\LogFiles\IN*.log | Get-NSPNpsLog -PacketType Access-Reject
    #>

    [CmdletBinding()]
    [OutputType([pscustomobject])]
    param(
        [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)][Alias('FullName')][string[]]$Path,
        [string]$UserName,
        [string[]]$PacketType,
        [string]$IASConfigPath = (Join-Path $env:SystemRoot 'System32\ias\ias.xml')
    )
    process {
        $files = @($Path)
        if (-not $Path) {
            $dir = if (Test-Path -LiteralPath $IASConfigPath) { (Get-NPSLogRotationInfo -IASConfigPath $IASConfigPath).LogDirectory } else { Join-Path $env:SystemRoot 'System32\LogFiles' }
            $files = @(Get-NPSActiveLogFiles -LogDirectory $dir | Select-Object -First 1 | ForEach-Object FullName)
            if (-not $files) { throw "No IN*.log files in $dir." }
        }
        foreach ($file in $files) {
            $entries = @(Read-NPSRadiusLog -Path $file)
            if ($UserName) {
                $keys = @($entries | Where-Object { $_.UserName -like $UserName -or $_.UserFQDN -like $UserName } | ForEach-Object { Get-NPSRadiusLogGroupKey -Entry $_ } | Select-Object -Unique)
                $entries = @($entries | Where-Object { $keys -contains (Get-NPSRadiusLogGroupKey -Entry $_) })
            }
            if ($PacketType) { $entries = @($entries | Where-Object { $PacketType -contains $_.PacketType }) }
            foreach ($e in $entries) { $e.PSObject.TypeNames.Insert(0, 'NSP.NPS.LogEntry'); $e }
        }
    }
}