How to Configure Windows Event Log Archiving on Windows Server 2012 R2

Windows Event Logs record a comprehensive audit trail of system activities, security events, application errors, and administrative actions. By default, event logs are stored in files on the local server and are overwritten when they reach their maximum size. For compliance, security auditing, and long-term troubleshooting purposes, it is essential to archive event logs to a permanent location before they are overwritten. Windows Server 2012 R2 supports event log archiving through subscription-based forwarding, scheduled archive scripts, and group policy-controlled log size management. This guide covers configuring log archiving, centralised collection, and automated retention.

Prerequisites

Administrator rights are required. An archival destination must be provisioned — either a network share with adequate capacity or a centralised log management server. Estimate storage requirements: a busy domain controller can generate 50-200 MB of Security event log data per day, while a file server typically generates 10-50 MB per day. Plan for at least 90 days of retention in accessible archives and longer-term cold storage for compliance requirements. Windows Remote Management (WinRM) must be enabled on source servers if event forwarding will be used.

Step 1: Configure Event Log Maximum Sizes

Increase the default event log maximum sizes to reduce overwrite frequency and provide a larger rolling buffer. Configure via Group Policy or PowerShell:

# Set log sizes for key event logs
# Security log: 512 MB (important for security auditing)
wevtutil sl Security /ms:536870912

# System log: 128 MB
wevtutil sl System /ms:134217728

# Application log: 128 MB
wevtutil sl Application /ms:134217728

# Verify settings
wevtutil gl Security | findstr "maxSize"
wevtutil gl System | findstr "maxSize"

Configure via Group Policy for domain-wide enforcement: Computer Configuration → Windows Settings → Security Settings → Event Log → Maximum security log size (512000 KB recommended).

Step 2: Set Retention Policy to Archive on Full

Configure event logs to archive rather than overwrite when the log is full. The archive mode creates a timestamped archive file before clearing the log:

# Set Security log to archive when full (do not overwrite events)
wevtutil sl Security /rt:false /ab:true

# This sets the retention mode:
# /rt:false = Do not retain old events (overwrite)
# /ab:true = Auto-backup when log is full

# Verify retention settings
wevtutil gl Security

Configure via PowerShell using the System.Diagnostics.Eventing namespace:

$logs = @("Security", "System", "Application")
foreach ($log in $logs) {
    $eventLog = [System.Diagnostics.Eventing.Reader.EventLogConfiguration]::new($log)
    $eventLog.IsEnabled = $true
    $eventLog.MaximumSizeInBytes = 128MB
    $eventLog.LogMode = [System.Diagnostics.Eventing.Reader.EventLogMode]::AutoBackup
    $eventLog.SaveChanges()
    Write-Host "Configured $log log"
}

Step 3: Create a Scheduled Event Log Archive Script

Archive event logs on a daily schedule, copying the current logs to a dated archive location before they roll over:

$archiveScript = @'
param(
    [string]$ArchivePath = "\LogServer01EventLogArchive",
    [int]$RetainDays = 90
)

$server = $env:COMPUTERNAME
$date = Get-Date -Format "yyyyMMdd"
$destDir = Join-Path $ArchivePath "$server$date"
New-Item -ItemType Directory -Path $destDir -Force | Out-Null

$logsToArchive = @("Security", "System", "Application", "Microsoft-Windows-TaskScheduler/Operational")

foreach ($logName in $logsToArchive) {
    $safeName = $logName -replace "/", "_" -replace " ", "_"
    $archiveFile = Join-Path $destDir "$safeName.evtx"
    
    try {
        wevtutil epl $logName $archiveFile /ow:true
        Write-Host "Archived: $logName -> $archiveFile"
    } catch {
        Write-Warning "Failed to archive $logName`: $_"
    }
}

# Remove archives older than retention period
Get-ChildItem -Path $ArchivePath -Directory | Where-Object {
    try {
        $folderDate = [datetime]::ParseExact($_.Name, "yyyyMMdd", $null)
        $folderDate -lt (Get-Date).AddDays(-$RetainDays)
    } catch { $false }
} | ForEach-Object {
    Remove-Item $_.FullName -Recurse -Force
    Write-Host "Removed old archive: $($_.FullName)"
}
'@

$archiveScript | Out-File "C:ScriptsArchiveEventLogs.ps1" -Encoding UTF8

$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NonInteractive -ExecutionPolicy Bypass -File C:ScriptsArchiveEventLogs.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
Register-ScheduledTask -TaskName "Daily Event Log Archive" -Action $action -Trigger $trigger -RunLevel Highest -User "SYSTEM"

Step 4: Archive Event Logs Using WEVTUTIL

WEVTUTIL is the built-in command-line tool for managing Windows event logs. Export a specific log to an EVTX file:

# Export the Security log to a file
wevtutil epl Security "\LogServer01ArchiveSecurity_20260515.evtx" /ow:true

# Export with a filter (last 24 hours only)
$startTime = (Get-Date).AddDays(-1).ToString("yyyy-MM-ddTHH:mm:ss")
wevtutil epl Security "C:TempSecurity_LastDay.evtx" /q:"*[System[TimeCreated[@SystemTime>='$startTime']]]" /ow:true

# Clear the Security log (after archiving - use with caution)
wevtutil cl Security

Step 5: Query Archived Logs with PowerShell

Archived EVTX files can be queried offline using Get-WinEvent without the events needing to be in the live event logs:

# Query an archived Security log file for failed logon events
Get-WinEvent -Path "\LogServer01ArchiveWS2012R2-SERVER0120260515Security.evtx" | Where-Object {$_.Id -eq 4625} | Select-Object TimeCreated, Message | Format-List

# Search multiple archive files for a specific time range
$archiveFiles = Get-ChildItem "\LogServer01ArchiveWS2012R2-SERVER01" -Filter "Security.evtx" -Recurse
foreach ($file in $archiveFiles) {
    Get-WinEvent -Path $file.FullName -ErrorAction SilentlyContinue | Where-Object {
        $_.Id -eq 4625 -and $_.TimeCreated -gt "2026-05-01"
    } | Select-Object TimeCreated, Message
}

Step 6: Set Up Log File Rotation with Group Policy

Apply event log settings domain-wide using Group Policy: Computer Configuration → Administrative Templates → Windows Components → Event Log Service → Security:

Enable and set: Specify the maximum log file size = 524288 KB (512 MB). Enable Configure log access: O:BAG:SYD:(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x1;;;BO)(A;;0x1;;;SO)(A;;0x1;;;S-1-5-32-573). Retain old events = Disabled (so log is overwritten rather than full). Back up log automatically when full = Enabled.

Step 7: Verify Archive Integrity

Verify archived EVTX files are readable and contain expected content:

$archiveFile = "\LogServer01ArchiveWS2012R2-SERVER0120260515Security.evtx"
$eventCount = (Get-WinEvent -Path $archiveFile -ErrorAction Stop | Measure-Object).Count
Write-Host "Archive $archiveFile contains $eventCount events"

# Check oldest and newest event times
$events = Get-WinEvent -Path $archiveFile
$oldest = ($events | Sort-Object TimeCreated | Select-Object -First 1).TimeCreated
$newest = ($events | Sort-Object TimeCreated | Select-Object -Last 1).TimeCreated
Write-Host "Date range: $oldest to $newest"

Summary

Event log archiving on Windows Server 2012 R2 is a critical component of security auditing, compliance, and long-term troubleshooting capability. By configuring appropriate log sizes, setting auto-backup retention modes, and implementing daily archiving scripts that copy EVTX files to a centralised network location, organisations maintain a searchable, long-term audit trail that survives log rotation. Regular verification of archive integrity and clear retention policies ensure event log data remains accessible and useful when security investigations or compliance audits require it.