Powershell : Retrieve Event ID's from Servers (matching criteria)


This PowerShell script was designed to address the challenge of monitoring Kerberos authentication issues across multiple domain controllers in an Active Directory environment. Specifically, it focuses on tracking events related to a specific service account and set of servers that may be experiencing authentication problems.

Purpose and Functionality

The script automates the otherwise tedious process of:

  1. Searching across all domain controllers for specific Kerberos-related event IDs (35, 36, 37, 38, 39)
  2. Filtering for events related to a particular service account or specific servers
  3. Compiling the results into a centralized log file for analysis
  4. Providing verbose on-screen output for real-time monitoring

You will need to see all relevant event ID's to ensure comprehensiveness.

Key Features

  1. Multi-DC Search: Automatically queries all domain controllers, eliminating the need to manually connect to each server
  2. Efficient Filtering: Uses PowerShell's FilterHashtable parameter to filter events directly at the source
  3. Flexible Matching: Implements OR logic to find events containing either the service account or any of the specified servers
  4. Detailed Output: Logs both to screen and file, with clear formatting and relevant details
Why would I use this script?

This script is particularly valuable for:

  • Troubleshooting Kerberos authentication failures
  • Investigating service account issues across multiple servers
  • Security teams monitoring for suspicious authentication activity
  • Regular auditing of authentication events

By automating what would otherwise be a manual and time-consuming process, this script enables quickly identify and respond to Kerberos-related issues before they impact users or services.

Time Limited

If you need to limit the script to a number of days of events then you can add this to the code to only select, in this example, the last 2 days or Events.

$startDate = (Get-Date).AddDays(-2)

$filter = @{
    LogName = 'System'
    ID = $eventID
    StartTime = $startDate
}

Script : DC-EventScanner.ps1

# Direct Kerberos Event Search - Using direct filtering by ID
# Searches for event IDs 35, 36, 37, 38, 39 from the System log

# Define variables for search criteria
$serviceAccount = @("ntlm.manager", "ntlm.manager2")
$serverNames = @("BearAppSrv1", "BearAppSrv2", "BearAppSrv3")
$eventIDs = @(35, 36, 37, 38, 39)

# Get current timestamp for log file naming
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
$logFile = "KerberosEvents_$timestamp.log"

# Display script information
Write-Host "Kerberos Event Search Script" -ForegroundColor Cyan
Write-Host "=============================" -ForegroundColor Cyan
Write-Host "Searching for events with IDs $($eventIDs -join ', ') related to EITHER:"
Write-Host "- Service Account: $serviceAccount"
Write-Host "Log file will be saved as: $logFile"
Write-Host "=============================" -ForegroundColor Cyan
Write-Host ""

# Get all domain controllers from current domain
Write-Host "Retrieving domain controllers..." -ForegroundColor Yellow
$domainControllers = Get-ADDomainController -Filter * | Select-Object -ExpandProperty Hostname
Write-Host "Found $(($domainControllers).Count) domain controllers" -ForegroundColor Green

# Initialize counter for reporting
$totalEventsFound = 0
$DCsWithEvents = 0

# Create empty log file
"Kerberos Event Search Results - $(Get-Date)" | Out-File -FilePath $logFile
"Events: $($eventIDs -join ', ') | Account: $serviceAccount OR Servers: $($serverNames -join ', ')" | Out-File -FilePath $logFile -Append
"=====================================================================" |
Out-File -FilePath $logFile -Append
"" | Out-File -FilePath $logFile -Append

# Loop through each domain controller
foreach ($dc in $domainControllers) {
    Write-Host "Searching on domain controller: $dc" -ForegroundColor Yellow   
    try {
        # Use direct filtering by ID for each event ID
        $matchingEvents = @()       
        foreach ($eventID in $eventIDs) {
            Write-Host "  Getting events with ID $eventID..." -NoNewline            

            # Create a filter for the specific ID
            $filter = @{
                LogName = 'System'
                ID = $eventID
            }           

            # Get events with this ID
           $idEvents = Get-WinEvent -FilterHashtable $filter -ComputerName $dc -ErrorAction SilentlyContinue           
            if ($idEvents) {
                Write-Host " found $($idEvents.Count) events" -ForegroundColor Gray               

                # Filter for service account or servers
                foreach ($event in $idEvents) {
                    $message = $event.Message
                    $hasAccount = $message -like "*$serviceAccount*"
                    $hasServer = $false                   
                    foreach ($server in $serverNames) {
                        if ($message -like "*$server*") {
                            $hasServer = $true
                            break
                        }
                    }                   
                    if ($hasAccount -or $hasServer) {
                        $matchingEvents += $event
                    }
                }
            } else {
                Write-Host " found 0 events" -ForegroundColor Gray
            }
        }       

        # Report on matching events
        if ($matchingEvents.Count -gt 0) {
            Write-Host "  Found $($matchingEvents.Count) matching events!" -ForegroundColor Green
            $totalEventsFound += $matchingEvents.Count
            $DCsWithEvents++           

            # Output DC header to log file
            "Domain Controller: $dc" | Out-File -FilePath $logFile -Append
            "Found $($matchingEvents.Count) matching events" | Out-File -FilePath $logFile -Append
            "-------------------------" | Out-File -FilePath $logFile -Append           
            # Process each event
            foreach ($event in $matchingEvents) {
                # Check which criteria matched
                $hasAccount = if ($event.Message -like "*$serviceAccount*") { "Yes" } else { "No" }
                $serverMatched = "None"
                foreach ($server in $serverNames) {
                    if ($event.Message -like "*$server*") {
                        $serverMatched = $server
                        break
                    }
                }                

                # Display event on screen
                Write-Host "  Event ID: $($event.Id) | Time: $($event.TimeCreated) | Provider: $($event.ProviderName)" -ForegroundColor White               

                # Write event to log file
                "Time: $($event.TimeCreated)" | Out-File -FilePath $logFile -Append
                "Event ID: $($event.Id)" | Out-File -FilePath $logFile -Append
                "Provider: $($event.ProviderName)" | Out-File -FilePath $logFile -Append
                "Level: $($event.LevelDisplayName)" | Out-File -FilePath $logFile -Append
                "Contains Account: $hasAccount" | Out-File -FilePath $logFile -Append
                "Contains Server: $serverMatched" | Out-File -FilePath $logFile -Append
                "Details:" | Out-File -FilePath $logFile -Append
                $event.Message | Out-File -FilePath $logFile -Append
                "" | Out-File -FilePath $logFile -Append
            }
            "" | Out-File -FilePath $logFile -Append
        } else {
            Write-Host "  No matching events found" -ForegroundColor Gray
        }
    }
    catch {
        Write-Host "  ERROR: Could not retrieve events from $dc" -ForegroundColor Red
        Write-Host "  $($_.Exception.Message)" -ForegroundColor Red
        "ERROR retrieving events from $dc - $($_.Exception.Message)" | Out-File -FilePath $logFile -Append
        "" | Out-File -FilePath $logFile -Append
    }
}

# Summary information
Write-Host ""
Write-Host "=============================" -ForegroundColor Cyan
Write-Host "Search Summary:" -ForegroundColor Cyan
Write-Host "Total events found: $totalEventsFound" -ForegroundColor $(if ($totalEventsFound -gt 0) {"Green"} else {"Yellow"})
Write-Host "DCs with matching events: $DCsWithEvents / $($domainControllers.Count)" ForegroundColor $(if ($DCsWithEvents -gt 0) {"Green"} else {"Yellow"})
Write-Host "Log file saved as: $logFile" -ForegroundColor White
Write-Host "=============================" -ForegroundColor Cyan

# Final summary to log file
"" | Out-File -FilePath $logFile -Append
"=====================================================================" |
Out-File -FilePath $logFile -Append
"Summary" | Out-File -FilePath $logFile -Append
"Total events found: $totalEventsFound" | Out-File -FilePath $logFile -Append
"DCs with matching events: $DCsWithEvents / $($domainControllers.Count)" | Out-File -FilePath $logFile -Append
"Search completed: $(Get-Date)" | Out-File -FilePath $logFile -Append

Previous Post Next Post

نموذج الاتصال