Automating Export for Windows Events Logs with PowerShell
I like to say cybersecurity is like an onion. It has many layers. In technical terms, we might say there are many vectors to protect, monitor and analyze. One common area is monitoring for activity with your Windows domain controllers. In Windows, the Event Viewer is the most common starting point for any activity analysis. The three core logs (Application, System and Security) provide details on information, warnings, errors and critical events. You can also configure Windows to log relevant cybersecurity activities like permission elevations and file deletions. The common issue we see is that the logs do not hold enough history for most auditing requirements. While you can increase the log sizes in Windows, this is not recommended. It will increase disk and performance demands on your servers. Also, Event Viewer is not a robust search and analysis tool. The best approach is to export your events. In this article, I take a straightforward approach to get the event logs exported to CSV files. The CSV format is much easier to work with than the proprietary EVTX Windows format. This approach does not require purchasing any software and relies solely on PowerShell. Once you have your logs exported, you can keep them as long as required and use the logs with other tools for analysis and reporting.
Objective
Easily export the three main Event logs from Windows to CSV files.
Application Log: Contains events logged by applications or programs, providing information about application errors, warnings, and informational events.
System Log: Records events logged by Windows system components, including driver failures, system errors, and other critical system events.
Security Log: Tracks security-related events such as login attempts, resource access, and changes to security settings, useful for auditing and monitoring security.
Overview of Steps
From the server or workstation, the first few steps must be done as local or domain Administrator.
Add the account name that will be running the scripts to the local security group Event Log Readers. It is not recommended to use an Administrator or Domain Admin account.
NOTE: If you have to do this for several computers in a domain, a GPO could be used.
2. Using an Administrator PowerShell session, run the following commands:
$acl = Get-Acl HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Security $rule = New-Object System.Security.AccessControl.RegistryAccessRule ("BUILTIN\Event Log Readers", "ReadKey", "Allow") $acl.SetAccessRule($rule) Set-Acl HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Security $acl
3. Confirm your PowerShell environment will allow running scripts. See Set-ExecutionPolicy (Microsoft.PowerShell.Security) - PowerShell | Microsoft Learn
Then, login with the user account for configuration the scheduled task to run the script.
Create a local folder to hold the script and downloaded files. Set folder permissions as needed. Verify sufficient disk space is available.
Create the script (see below for details).
Create the scheduled task. The frequency for running will vary based on your environment, activity and Event Log size settings.
Advanced Tips:
Use PowerShell to empty the logs after downloading
Enhance the script to offload the exported scripts to another storage location for protection
Import the scripts to another program or dashboard for review and alerting
Exporting Event Logs
Method 1 - Keeping it Simple
The Get-WinEvent PowerShell command is your tool for this task. If you just want to get the task done, here are your three lines of code:
# Export Application log errors, warnings, and critical events to CSV Get-WinEvent -LogName Application -FilterXPath "*[System[(Level=1 or Level=2 or Level=3)]]" | Export-Csv "application_logs.csv" -NoTypeInformation # Export System log errors, warnings, and critical events to CSV Get-WinEvent -LogName System -FilterXPath "*[System[(Level=1 or Level=2 or Level=3)]]" | Export-Csv "system_logs.csv" -NoTypeInformation # Export Security log audit successes and failures to CSV Get-WinEvent -LogName Security -FilterXPath "*[System[(Keywords='0x8020000000000000' or Keywords='0x8010000000000000')]]" | Export-Csv security_logs.csv" -NoTypeInformation
Method 2 - Getting a Little Fancy
This version gives you a variable at the beginning to set your target export folder. It also creates a daily export log file tracking the export times.
# Define the folder location for CSV files $folderPath = "C:\EventLogs" # Ensure the folder exists if (-not (Test-Path -Path $folderPath)) { / / New-Item -Path $folderPath -ItemType Directory } # Define the log file name with the current date $logFileName = "ExpLog_$(Get-Date -Format 'yyyy-MM-dd').txt" $logFilePath = Join-Path -Path $folderPath -ChildPath $logFileName # Function to write to the execution log function Write-Log { / / param ( / / / / [string]$message / / ) / / $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' / / $logMessage = "$timestamp - $message" / / Add-Content -Path $logFilePath -Value $logMessage } # Function to export logs and handle errors function Export-Log { / / param ( / / / / [string]$logName, / / / / [string]$filterXPath, / / / / [string]$outputPath / / ) / / Write-Log "Starting export for $logName log" / / $startTime = Get-Date / / try { / / / / $events = Get-WinEvent -LogName $logName -FilterXPath $filterXPath -ErrorAction Stop / / / / if ($events.Count -eq 0) { / / / / / / Write-Log "No events found for $logName log." / / / / } else { / / / / / / $events | Export-Csv -Path $outputPath -NoTypeInformation / / / / / / Write-Log "Exported $logName log to $outputPath." / / / / } / / } catch { / / / / Write-Log "No events found for $logName log." / / } / / $endTime = Get-Date / / Write-Log "Completed export for $logName log. Start time: $startTime, End time: $endTime" } # Export Application log errors, warnings, and critical events to CSV Export-Log -logName "Application" -filterXPath "*[System[(Level=1 or Level=2 or Level=3)]]" -outputPath "$folderPath\application_logs.csv" # Export System log errors, warnings, and critical events to CSV Export-Log -logName "System" -filterXPath "*[System[(Level=1 or Level=2 or Level=3)]]" -outputPath "$folderPath\system_logs.csv" # Export Security log audit successes and failures to CSV Export-Log -logName "Security" -filterXPath "*[System[(Keywords='0x8020000000000000' or Keywords='0x8010000000000000')]]" -outputPath "$folderPath\security_logs.csv" # Export Setup log events to CSV Export-Log -logName "Setup" -filterXPath "*[System[(Level=1 or Level=2 or Level=3)]]" -outputPath "$folderPath\setup_logs.csv" # Export ForwardedEvents log events to CSV Export-Log -logName "ForwardedEvents" -filterXPath "*[System[(Level=1 or Level=2 or Level=3)]]" -outputPath "$folderPath\forwarded_events_logs.csv"
What’s Next?
Capturing of the event logs is just the beginning and minimum action required for auditing. Here are some ideas on how to make this even better:
Use Get-WinEvent to make sure all computers have a good minimum log size so events are not lost. You can query the log size in PowerShell using “(Get-WinEvent -ListLog Security).FileSize / 1MB”
Enhance the script to write your own event into each log at the export execution. Then, read for that event to know where to begin exporting each time.
Enhance the script to also export the Setup and ForwardedEvents logs. The Setup log captures events related to the installation and configuration of software and system components. The ForwardedEvents log aggregates events forwarded from multiple sources.
Import your CSV files into PowerBI or another data analysis tool/program for intelligent review. It is important to establish baselines and identify suspicious events.
Consider using the exports files with a SIEM or other security monitoring tool.
I hope this article was helpful. Stay safe and keep improving your cybersecurity resilience!