Created
July 9, 2023 16:37
-
-
Save Qazeer/4936ec6c9fa511500f9496d0ceacab22 to your computer and use it in GitHub Desktop.
Recursively process the source directory to execute Winlogbeat once on all EVTX file(s) found.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Recursively process the source directory to execute Winlogbeat once on all EVTX file(s) found. | |
This PowerShell script is basically a wrapper to make Winlogbeat recursive, with out a predefined set of EVTX files to look for. | |
.PARAMETER WinlogbeatBinary | |
Specify the winlogbeat.exe binary full path. The binary must be within the winlogbeat program folder. | |
.PARAMETER InputDir | |
Specify the folder which contains the EVTX file(s). The folder will be recursively processed. | |
.PARAMETER OutputDir | |
Specify the folder where the Winlogbeat outputs will be placed. | |
#> | |
[CmdletBinding()] | |
param | |
( | |
[Parameter(Mandatory = $true, | |
Position = 1, | |
HelpMessage = 'Specify the winlogbeat.exe binary full path. The binary must be within the winlogbeat program folder.')] | |
[String]$WinlogbeatBinary, | |
[Parameter(Mandatory = $true, | |
Position = 2, | |
HelpMessage = 'Specify the folder which contains the EVTX file(s). The folder will be recursively processed.')] | |
[String]$InputDir, | |
[Parameter(Mandatory = $true, | |
Position = 3, | |
HelpMessage = 'Specify the folder where the Winlogbeat outputs will be placed.')] | |
[String]$OutputDir | |
) | |
$WINLOGBEAT_BASE_CONFIG = ' | |
# Description: Winlogbeat configuration generated by Execute-Winlogbeat.ps1. | |
winlogbeat.event_logs: | |
<LOG_SPECIFIERS> | |
path.data: "${TEMPORARY_FOLDER}" | |
winlogbeat.registry_file: "${TEMPORARY_FOLDER}\\winlogbeat_registry_file.yml" | |
disk: | |
read_ahead: 8092 | |
processors: | |
- drop_fields: | |
fields: ["beat", "metadata", "log", "agent", "ecs", "event", "host"] | |
logging.level: error | |
output.file: | |
path: "${OUTPUT_FOLDER}" | |
number_of_files: 1024 | |
rotate_every_kb: 500000 | |
rotate_on_startup: false | |
' | |
$WINLOGBEAT_BASE_SPECIFIER = ' | |
- name: "<EVTX_FILE>" | |
no_more_events: stop | |
' | |
try { | |
# Check if $WinlogbeatBinary exists. | |
if (-not (Test-Path -Path $WinlogbeatBinary -PathType Leaf)) { | |
throw "The $WinlogbeatBinary binary does not exist." | |
} | |
# Check if $InputDir exists. | |
if (-not (Test-Path -Path $InputDir -PathType Container)) { | |
throw "The directory $InputDir does not exist." | |
} | |
# Create the $OutputDir path if it does not exist. | |
if (-not (Test-Path -Path $OutputDir -PathType Container)) { | |
# Create the directory, but do not prompt for confirmation (-Confirm:$false). | |
[void] (New-Item -ItemType Directory -Path $OutputDir -Confirm:$false) | |
} | |
# Look for evtx files in $InputDir. | |
$evtxRegex = '*.evtx' | |
$files = Get-ChildItem -Path $InputDir -Filter $evtxRegex -Recurse -ErrorAction Stop | |
# Check if files were found. | |
if ($null -eq $files -or $files.Count -eq 0) { | |
Write-Host "No $evtxRegex file(s) were found in $InputDir" | |
} | |
else { | |
Write-Host "Found $($files.Count) $evtxRegex file(s) in $InputDir" | |
} | |
# Add each EVTX file found in the specifiers string list. | |
$winlogbeatSpecifiers = "" | |
foreach ($file in $files) { | |
$winlogbeatSpecifiers += $WINLOGBEAT_BASE_SPECIFIER.Replace("<EVTX_FILE>", $file.FullName.Replace('\', '\\')) | |
} | |
# Create the temporary Winlogbeat folder. | |
$WinlogbeatTempFolder = "$(Join-Path $OutputDir "Winlogbeat_temp_$([guid]::NewGuid().ToString())")" | |
[void] (New-Item -ItemType Directory -Path $WinlogbeatTempFolder -Confirm:$false) | |
# Create the temporary Winlogbeat config. | |
$WinlogbeatConfig = $WINLOGBEAT_BASE_CONFIG.Replace("<LOG_SPECIFIERS>", $winlogbeatSpecifiers) | |
$WinlogbeatConfigPath = "$(Join-Path $WinlogbeatTempFolder "Winlogbeat_KAPE_config.yml")" | |
Write-Host "Writing the temporary Winlogbeat config to '$WinlogbeatConfigPath'" | |
Set-Content -Path $WinlogbeatConfigPath -Value $WinlogbeatConfig | |
Start-Sleep 1 | |
# Execute winlogbeat, using the created configuration file and the outputdir parameter (specified to Winlogbeat through a process scoped environment variable). | |
$arguments = "-e", "-c", "`"$WinlogbeatConfigPath`"", "-E", "`"OUTPUT_FOLDER=$($OutputDir.Replace('\', '\\'))`"", "-E", "`"TEMPORARY_FOLDER=$($WinlogbeatTempFolder.Replace('\', '\\'))`"" | |
Write-Host "Command: $WinlogbeatBinary $arguments" | |
Start-Process -NoNewWindow -Wait $WinlogbeatBinary -ArgumentList $arguments -RedirectStandardOutput "$(Join-Path $WinlogbeatTempFolder "Winlogbeat_stdout.log")" # -RedirectStandardError "$(Join-Path $OutputDir "Winlogbeat_stderr.log")" | |
} | |
catch [System.Exception] { | |
# If an error occurred, print error details | |
Write-Error "An error occurred while running this script" | |
Write-Error "Exception type: $($_.Exception.GetType().FullName)" | |
Write-Error "Exception message: $($_.Exception.Message)" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment