Public/diagnostics/Get-LogonEvents.ps1
function Get-LogonEvents { <# .SYNOPSIS Retrieves and displays user logon events from the Windows Security log. .DESCRIPTION The Get-LogonEvents function retrieves logon events (EventID 4624) from the Security log for a specified time period. It filters out system accounts and displays the results in a grid view with detailed information including timestamp, account name, logon type (with description), and source IP/computer. This function is useful for security auditing and monitoring user access to systems. .PARAMETER Days Specifies the number of days to look back for logon events. Default is 1 day. .PARAMETER ShowGridView If specified, displays the results in a grid view window. Default is $true. .PARAMETER IncludeSystemAccounts If specified, includes system accounts in the results. Default is $false. .EXAMPLE Get-LogonEvents Retrieves all user logon events from the past day and displays them in a grid view. .EXAMPLE Get-LogonEvents -Days 7 -ShowGridView $false Retrieves logon events from the past week and returns them as objects without displaying the grid view. .EXAMPLE Get-LogonEvents -Days 3 | Where-Object {$_.LogonTypeDescription -eq "Remote Desktop"} Retrieves logon events from the past 3 days and filters for just Remote Desktop connections. .NOTES Logon Types: 2 = Interactive (Local logon) 3 = Network (Connection to shared folder) 4 = Batch (Scheduled task) 5 = Service (Service startup) 7 = Unlock (Unlocking a previously locked session) 8 = NetworkCleartext (Most often indicates a logon to IIS with "basic authentication") 9 = NewCredentials (A process ran using RunAs) 10 = RemoteInteractive (Terminal Services, Remote Desktop or Remote Assistance) 11 = CachedInteractive (Logon using cached domain credentials when a DC is not available) #> param ( [int]$Days = 1, [bool]$ShowGridView = $true, [switch]$IncludeSystemAccounts = $false ) $before = Get-Date $after = (Get-Date).AddDays(-$Days) $result = @() Write-Host "Retrieving logon events from $after to $before..." -ForegroundColor Cyan # Build the filter for system accounts $filter = {$true} if (-not $IncludeSystemAccounts) { $filter = { ($_.ReplacementStrings[5] -notmatch '\$') -and ($_.ReplacementStrings[5] -notmatch 'ANONYMOUS LOGON') -and ($_.ReplacementStrings[5] -notmatch 'SYSTEM') } } # EventID 4624 = logon $audit = Get-EventLog Security -InstanceId 4624 -Before $before -After $after | Where-Object $filter if (-not $audit) { Write-Host "No logon events found for the specified period." -ForegroundColor Yellow return $null } Write-Host "Processing $($audit.Count) logon events..." -ForegroundColor Cyan foreach ($event in $audit) { $time = $event.TimeGenerated | Get-Date -Format "yyyy-MM-dd HH:mm:ss" $account = $event.ReplacementStrings[5] $domain = $event.ReplacementStrings[6] $logonTypeCode = $event.ReplacementStrings[8] $sourceIP = $event.ReplacementStrings[18] # Translate logon type code to a description $logonTypeDescription = switch ($logonTypeCode) { 2 { "Interactive (Local logon)" } 3 { "Network (Shared folder)" } 4 { "Batch (Scheduled task)" } 5 { "Service" } 7 { "Unlock" } 8 { "NetworkCleartext" } 9 { "NewCredentials (RunAs)" } 10 { "Remote Desktop" } 11 { "Cached Domain Logon" } default { "Type $logonTypeCode (Unknown)" } } # Create and add the result object $obj = [PSCustomObject]@{ Time = $time Account = "$domain\$account" LogonType = $logonTypeCode LogonTypeDescription = $logonTypeDescription SourceIP = if ($sourceIP -and $sourceIP -ne "-") { $sourceIP } else { "Local" } } $result += $obj } # Output the results if ($ShowGridView) { $result | Sort-Object -Property Time -Descending | Out-GridView -Title "Logon Events: Past $Days Day(s)" } return $result } |