This PowerShell script analyzes the Application, System, and Security Windows Event Logs on the local machine and estimates log volume over time. It reports:
- Current oldest and newest event timestamps
- Total events currently available in the log
- Events per second (EPS) based on the visible time window
- Estimated monthly events (30-day projection from EPS)
- Average event size (bytes) based on current log file size and record count
- Estimated monthly size (MB) using the average event size and estimated monthly events
- Configured maximum log size (MB)
The results are displayed in a table for the three core logs: Application, System, Security.
- Quickly understand how fast your logs fill up
- Estimate how much storage you may need per month
- Identify whether configured log size is adequate for your event volume
- Provide a baseline for SIEM/Sentinel cost estimation or retention planning
For each log (Application, System, Security):
- Fetches the oldest and newest events (
Get-WinEvent). - Reads log metadata (
Get-WinEvent -ListLog), includingRecordCount,FileSize, andMaximumSizeInBytes. - Calculates:
- EPS (events/second) from the observed time window
- Estimated Monthly Events using EPS × 30 days
- Average Event Size =
FileSize / RecordCount(bytes) - Estimated Monthly Size =
Estimated Monthly Events × Avg Event Size(converted to MB)
- Prints a formatted table with the computed metrics.
Hostname— Local machine nameLogName— One ofApplication,System,SecurityEPS— Events/second over the visible time rangeFirstEvent— Timestamp of the oldest event currently in the logLastEvent— Timestamp of the newest event currently in the logTotalEvents— Current number of events in the logAvgEventSize_Bytes— Average event size in bytes (from file size / record count)EstimatedMonthlyEvents— EPS projected over 30 daysEstimatedMonthlySize_MB— Projected size for 30 days (MB)LogConfiguredSize_MB— Log’s configured maximum size (MB)
- PowerShell 5.1+ (Windows) or PowerShell 7+
- Local ability to run:
Get-WinEvent -LogName <name>Get-WinEvent -ListLog <name>
- Sufficient permissions to read Application, System, and Security logs
Reading Security may require elevation. Run PowerShell as Administrator if you see access errors.
- Save the script as
Get-WinEventLog-Size-And-Estimate.ps1. - Open PowerShell (run as Administrator if needed).
- Execute:
.\Get-WinEventLog-Size-And-Estimate.ps1
- You’ll see a table like: Hostname LogName EPS FirstEvent LastEvent TotalEvents AvgEventSize_Bytes EstimatedMonthlyEvents EstimatedMonthlySize_MB LogConfiguredSize_MB -------- ------- --- ---------- --------- ----------- ------------------ ---------------------- ----------------------- -------------------- HOST123 Application 0.0123 11/12/2025 08:01:02 11/14/2025 11:20:45 123456 512.42 31968 15.62 2048 HOST123 System 0.0045 11/10/2025 09:10:00 11/14/2025 11:21:01 45678 478.03 11664 5.31 2048 HOST123 Security 0.0891 11/13/2025 13:00:12 11/14/2025 11:21:30 987654 392.18 231624 86.42 2048
# Define the log types to analyze
$logNames = @("Application", "System", "Security")
# Get the computer name
$hostname = $env:COMPUTERNAME
# Prepare results
$results = @()
foreach ($log in $logNames) {
try {
# Get first (oldest) event
$firstEventObj = Get-WinEvent -LogName $log -MaxEvents 1 -Oldest
$firstEvent = $firstEventObj.TimeCreated
# Get last (newest) event
$lastEventObj = Get-WinEvent -LogName $log -MaxEvents 1
$lastEvent = $lastEventObj.TimeCreated
# Get log info
$logInfo = Get-WinEvent -ListLog $log
$totalEvents = $logInfo.RecordCount
$logSizeBytes = $logInfo.FileSize
$logSizeMB = :Round($logInfo.MaximumSizeInBytes / 1MB, 2)
# Time delta in seconds
if ($firstEvent -and $lastEvent -and $firstEvent -ne $lastEvent) {
$timeSpan = ($lastEvent - $firstEvent).TotalSeconds
$eps = :Round($totalEvents / $timeSpan, 4)
$monthlySeconds = 30 * 24 * 60 * 60
$monthlyEstimate = :Round($eps * $monthlySeconds)
} else {
$eps = 0
$monthlyEstimate = 0
}
# Estimate average event size in bytes
if ($totalEvents -gt 0) {
$avgEventSizeBytes = :Round($logSizeBytes / $totalEvents, 2)
} else {
$avgEventSizeBytes = 0
}
# Estimate monthly size in MB
$estimatedMonthlySizeMB = :Round(($monthlyEstimate * $avgEventSizeBytes) / 1MB, 2)
# Add to results
$results += [PSCustomObject]@{
Hostname = $hostname
LogName = $log
EPS = $eps
FirstEvent = $firstEvent
LastEvent = $lastEvent
TotalEvents = $totalEvents
AvgEventSize_Bytes = $avgEventSizeBytes
EstimatedMonthlyEvents = $monthlyEstimate
EstimatedMonthlySize_MB = $estimatedMonthlySizeMB
LogConfiguredSize_MB = $logSizeMB
}
} catch {
Write-Warning "Failed to process log '$log': $_"
}
}
# Display results as a table
$results | Format-Table -AutoSize- EPS & projections are based on the currently visible events in the log. If your log overwrites frequently (small max size), the visible window may be short and over‑represent recent burstiness.
- Average event size is approximated via
FileSize / RecordCount. This assumes file size corresponds to the current set of records and that storage overhead is negligible. - Estimated monthly size uses a fixed 30 days (2,592,000 seconds).
- If no events exist or times are identical, EPS is set to 0 and estimates are 0.
- Security log access may require elevated privileges.
If you’d like to save results, add one of the following after the table output:
CSV:
$results | Export-Csv -NoTypeInformation -Path .\EventLog_Estimates.csv -Encoding UTF8JSON:
$results | ConvertTo-Json -Depth 3 | Out-File .\EventLog_Estimates.json -Encoding UTF8- Access denied / empty results for Security
Run PowerShell as Administrator. - Slow on very large logs
Get-WinEventis optimized vs.Get-EventLog, but on extremely large logs it can still take time. - EPS looks too high/low
CheckFirstEventandLastEventto see how wide the visible time window is and whether log rollover is causing a narrow observation period.
Issues and PRs are welcome. Please include:
- OS build and PowerShell version
- Sample output and log sizes
- Repro steps
Authored by @MathijsVermaat. Feedback and improvements are appreciated.