Public/Get-NSPNpsAuthAttempt.ps1
|
function Get-NSPNpsAuthAttempt { <# .SYNOPSIS One row per RADIUS authentication attempt in the NPS log: who, from which NAS, which policies, and the outcome - Accepted, Rejected, or NoDecision (the request was logged but no Accept/Reject followed, e.g. discarded before Network Policy evaluation). .DESCRIPTION Groups log entries the way NPS Manager's paired view does (by AcctSessionId, else server + time + user) and summarises each group: the first Access-Request and the last Accept/Reject. Takes entries from the pipeline (Get-NSPNpsLog) or reads the log itself. .PARAMETER Path Log file(s). Default: the newest IN*.log in the configured log folder. .PARAMETER UserName Only attempts by this user (wildcards allowed). .PARAMETER Outcome Only attempts with this outcome. .EXAMPLE Get-NSPNpsAuthAttempt -Outcome Rejected | Format-Table Time, UserName, Reason, NetworkPolicy .EXAMPLE Get-NSPNpsLog -Path .\IN2610.log | Get-NSPNpsAuthAttempt -UserName '*jdoe*' #> [CmdletBinding(DefaultParameterSetName = 'File')] [OutputType([pscustomobject])] param( [Parameter(ParameterSetName = 'File')][string[]]$Path, [Parameter(ParameterSetName = 'Entries', ValueFromPipeline)]$InputObject, [string]$UserName, [ValidateSet('Accepted', 'Rejected', 'NoDecision')][string[]]$Outcome ) begin { $buffer = New-Object Collections.Generic.List[object] } process { if ($PSCmdlet.ParameterSetName -eq 'Entries') { foreach ($e in @($InputObject)) { $buffer.Add($e) } } } end { $entries = if ($PSCmdlet.ParameterSetName -eq 'Entries') { $buffer.ToArray() } else { $logArgs = @{}; if ($Path) { $logArgs.Path = $Path }; if ($UserName) { $logArgs.UserName = $UserName } @(Get-NSPNpsLog @logArgs) } foreach ($grp in @($entries | Group-Object -Property { Get-NPSRadiusLogGroupKey -Entry $_ })) { $rows = @($grp.Group) $req = $rows | Where-Object { $_.PacketType -eq 'Access-Request' } | Select-Object -First 1 if (-not $req) { continue } $decision = $rows | Where-Object { $_.PacketType -in 'Access-Accept', 'Access-Reject' } | Select-Object -Last 1 $result = if (-not $decision) { 'NoDecision' } elseif ($decision.PacketType -eq 'Access-Accept') { 'Accepted' } else { 'Rejected' } if ($UserName -and -not ($req.UserName -like $UserName -or $req.UserFQDN -like $UserName)) { continue } if ($Outcome -and $Outcome -notcontains $result) { continue } $last = if ($decision) { $decision } else { $req } [pscustomobject]@{ PSTypeName = 'NSP.NPS.AuthAttempt' Time = "$($req.RecordDate) $($req.RecordTime)" UserName = $req.UserName UserFQDN = $(if ($decision -and $decision.UserFQDN) { $decision.UserFQDN } else { $req.UserFQDN }) Outcome = $result Reason = $last.ReasonCode ReasonCodeRaw = $last.ReasonCodeRaw NetworkPolicy = $last.PolicyName ConnectionPolicy = $(if ($last.ProxyPolicyName) { $last.ProxyPolicyName } else { $req.ProxyPolicyName }) Nas = $(if ($req.ClientFriendlyName) { $req.ClientFriendlyName } else { $req.ClientIPAddress }) NasIPAddress = $req.NASIPAddress CallingStation = $req.CallingStationID AuthType = $last.AuthenticationType EapType = $last.EAPFriendlyName ChallengeRounds = @($rows | Where-Object { $_.PacketType -eq 'Access-Challenge' }).Count FramedIPAddress = $(if ($decision) { $decision.FramedIPAddress }) RadiusServer = $req.RadiusServer } } } } |