Skip to content

Instantly share code, notes, and snippets.

@Qazeer
Created July 9, 2023 16:37
Show Gist options
  • Save Qazeer/4936ec6c9fa511500f9496d0ceacab22 to your computer and use it in GitHub Desktop.
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.
<#
.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