Skip to content

03 · Event Logs

Windows Event Log Forensics: EVTX, Event IDs and Hunting

A practitioner guide to Windows event logs: EVTX format, key channels, Security and Sysmon event IDs, audit policy, cleared-log recovery and hunting tools.

Published on 11 min read

Windows event logs are the closest thing to a flight recorder that most Windows hosts have: logons, process launches, service installs, PowerShell and remote access all land there when auditing allows it. By the end of this guide you will know where the logs live and how they roll over, which channels and event IDs answer which questions, what the default audit policy silently misses, and how to recover evidence after someone clears the logs.

EVTX format and location

Since Windows Vista, logs are stored as binary XML in .evtx files under %SystemRoot%\System32\winevt\Logs. Each channel gets its own file, and a / in the channel name becomes %4 on disk, so Microsoft-Windows-PowerShell/Operational is stored as Microsoft-Windows-PowerShell%4Operational.evtx. XP and Server 2003 used the older .evt format in System32\config. The Windows event logs artifact page summarizes the layout.

Internally an EVTX file has a 4 KB file header (signature ElfFile) followed by 64 KB chunks (signature ElfChnk). Each chunk holds event records that start with the magic bytes 2A 2A 00 00 and carry their own EventRecordID and timestamp. Records use templates stored inside the chunk, which matters later: a chunk is self-contained enough to be parsed on its own when carved out of free space.

The path of a classic log can be changed. Check HKLM\SYSTEM\CurrentControlSet\Services\EventLog\<LogName> (value File) and, for the newer channels, HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels\<Channel> before assuming the default folder is complete.

Retention, size and rollover

Logs have a size limit, not a time limit. On Windows 7 and later Security, System and Application default to roughly 20 MB, and many Operational channels are much smaller (often around 1 MB). When full, the default behaviour is to overwrite the oldest events. Two other modes exist: archive the log when full (the AutoBackupLogFiles value, which leaves Archive-<Log>-<timestamp>.evtx files next to the live log) and do not overwrite.

Practical consequences:

  • On a domain controller or busy file server the Security log may cover only a few hours. Always note the oldest record per log before stating "no event was found".
  • Enterprise GPOs frequently raise the sizes; read the actual MaxSize rather than assuming defaults.
  • Logs forwarded to a SIEM or Windows Event Forwarding collector may outlive the local copy. Ask for them early.
# Size, mode and record count for a log
wevtutil gl Security
Get-WinEvent -ListLog Security, System, 'Microsoft-Windows-PowerShell/Operational' |
  Select-Object LogName, MaximumSizeInBytes, LogMode, RecordCount, FileSize

# Oldest surviving event in a collected file
Get-WinEvent -Path E:\case\Logs\Security.evtx -Oldest -MaxEvents 1 | Select-Object TimeCreated, RecordId

Channels that matter

ChannelWhy you open it
SecurityAuthentication, privilege use, process creation, account and policy changes
SystemService installs (7045), service state, log clearing (104), boot and shutdown (6005/6006/6008)
ApplicationApplication crashes, installers, some security products
Microsoft-Windows-TerminalServices-LocalSessionManager/OperationalRDP and console sessions: 21 logon, 22 shell start, 23 logoff, 24 disconnect, 25 reconnect
Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational1149: RDP user authentication succeeded at the network level, with source IP
Microsoft-Windows-PowerShell/Operational4103 module logging, 4104 script block logging
Microsoft-Windows-Sysmon/OperationalSysmon telemetry, only if Sysmon is installed
Microsoft-Windows-TaskScheduler/Operational106 task registered, 140 updated, 141 deleted, 200/201 action started/completed
Microsoft-Windows-Windows Defender/Operational1116/1117 detection and action, 5001 real-time protection disabled, 5007 configuration change
Microsoft-Windows-WMI-Activity/Operational5857 provider loaded, 5860 temporary and 5861 permanent event subscriptions
Microsoft-Windows-Bits-Client/Operational3 job created, 59/60 transfer started/stopped with the URL, 4 job completed

RDP specifics are on the RDP connections page, PowerShell on the PowerShell page, Defender on the Windows Defender page, and WMI and BITS on the WMI repository and BITS jobs pages. Some channels, TaskScheduler in particular, may be disabled or very small depending on the build and configuration, so their absence is not proof that nothing happened.

Core Security event IDs

Logons and sessions

4624 (successful logon) and 4625 (failed logon) are the backbone of any intrusion timeline. The field that turns them into a story is LogonType (see logon type):

Logon typeMeaningTypical source
2InteractiveConsole logon, runas without /netonly
3NetworkSMB share access, PsExec-style tools, WinRM (network auth)
4BatchScheduled tasks
5ServiceServices starting under an account
7UnlockWorkstation unlock
8NetworkCleartextBasic auth, some IIS scenarios
9NewCredentialsrunas /netonly, some credential-injection tools
10RemoteInteractiveRDP
11CachedInteractiveDomain logon with cached credentials, no DC reachable

For 4625, read Status and SubStatus: 0xC000006A is a wrong password for a valid account, 0xC0000064 a non-existent user, 0xC0000234 a locked-out account. A burst of 0xC0000064 against many names looks like spraying or enumeration, while repeated 0xC000006A on one account looks like guessing.

4634 is a logoff and 4647 a user-initiated logoff; pair them with 4624 on TargetLogonId to get session duration, knowing that network logons often log off within seconds. 4648 (logon with explicit credentials) shows the account typing credentials for another identity, which is common with runas and lateral movement tools; it is logged on the source machine. 4672 (special privileges assigned) follows a 4624 whenever the new session holds admin-level privileges, so 4624 plus 4672 with the same logon ID means an administrative session.

Process creation

4688 records a new process with its image path, parent process (Windows 10 and later) and token elevation type. It is only produced when Audit Process Creation is enabled, and the CommandLine field is only populated when the policy Include command line in process creation events is set (registry value ProcessCreationIncludeCmdLine_Enabled under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit). That setting is native to Windows 8.1 and Server 2012 R2 and later; older systems needed an update. Link a 4688 back to its session through SubjectLogonId, which matches the TargetLogonId of the originating 4624.

Persistence and account changes

  • 4697 (Security) and 7045 (System): a service was installed. 7045 is logged by the Service Control Manager regardless of audit policy; 4697 needs Audit Security System Extension. See the services page.
  • 4698: scheduled task created, with the full task XML in the event. 4699 deleted, 4702 updated. Requires Audit Other Object Access Events. See the scheduled tasks page.
  • 4720 user account created, 4722 enabled, 4724 password reset attempt by another account, 4728 member added to a security-enabled global group, 4732 member added to a security-enabled local group (for example Administrators).

Tampering

  • 1102: the Security log was cleared, with the account that did it. It is written whatever the audit policy.
  • 104 (System): another log was cleared.
  • 4719: system audit policy was changed. An attacker disabling process or logon auditing right before acting is a strong signal.
  • 1100: the Event Log service shut down. Outside a matching reboot (6006, then 6005 at next boot) it deserves attention.

Audit policy: what is and isn't logged by default

Default audit policy varies by Windows version and is usually overridden by domain GPOs, so never guess: collect auditpol /get /category:* from the live system, or read the effective policy from the Security hive and GPO files on a dead box. As a rough rule on a stock Windows 10/11 client:

  • Logged: logon and logoff (4624, 4625, 4634, 4647), special logon (4672), user account and security group management (4720, 4732...), audit policy change (4719), log clearing (1102), and 7045 in System.
  • Not logged: process creation (4688), scheduled task object events (4698), service install in Security (4697), file and registry object access, and detailed Kerberos service ticket events on member machines.

Missing categories are the single biggest reason an investigation "finds nothing" in the Security log. When they are off, fall back to Prefetch, Amcache, the TaskScheduler and PowerShell channels, and Sysmon if present.

# Effective audit policy on a live host
auditpol /get /category:*

# Is command-line capture enabled?
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit' -ErrorAction SilentlyContinue

Sysmon essentials

Sysmon is a free Sysinternals driver and service that writes rich ETW-sourced telemetry to Microsoft-Windows-Sysmon/Operational. Its value depends entirely on the configuration file deployed, so collect the config (from the registry or the deployment share) along with the log. The five IDs you will use most:

Sysmon IDEventWhat it gives you
1Process creationCommand line, hashes, parent process and command line, ProcessGuid, LogonId
3Network connectionProcess, source and destination IP and port; often filtered heavily by configs
11File createFiles dropped by a process, with creation time
13Registry value setRun keys, services and other persistence writes
22DNS queryDomain requested and the process that asked

ProcessGuid is unique per process instance, unlike PIDs that are reused, so pivot on it to build a process tree. Also useful: 7 (image loaded), 8 (CreateRemoteThread), 10 (process access, for example to lsass.exe) and 19 to 21 (WMI event subscriptions).

PowerShell 4103 and 4104

4104 (script block logging) records the text of script blocks as they are compiled, after deobfuscation layers such as -EncodedCommand or Invoke-Expression strings are resolved. It is enabled by the policy value EnableScriptBlockLogging under HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging. Even without that policy, PowerShell 5 logs script blocks it considers suspicious as warning-level 4104 events, which regularly saves investigations. Long scripts are split across several 4104 records sharing a ScriptBlockId, numbered with MessageNumber and MessageTotal; reassemble them before reading.

4103 (module logging) records pipeline execution details and parameter bindings for the modules configured under ModuleLogging. It is noisier but shows what commands actually ran with which arguments. The classic Windows PowerShell log adds 400/403 (engine start and stop) with a HostApplication field containing the launching command line, which works even on hosts with no other PowerShell logging.

# Reassemble script blocks from a collected Operational log
Get-WinEvent -FilterHashtable @{Path='E:\case\Logs\Microsoft-Windows-PowerShell%4Operational.evtx'; Id=4104} |
  ForEach-Object {
    $d = ([xml]$_.ToXml()).Event.EventData.Data
    [pscustomobject]@{
      Time    = $_.TimeCreated.ToUniversalTime()
      BlockId = ($d | Where-Object Name -eq 'ScriptBlockId').'#text'
      Part    = ($d | Where-Object Name -eq 'MessageNumber').'#text'
      Text    = ($d | Where-Object Name -eq 'ScriptBlockText').'#text'
    }
  } | Sort-Object BlockId, {[int]$_.Part}

Recovering from cleared logs

A 1102 or 104 tells you that a log was cleared and who did it. Getting the content back is a separate job, and anti-forensics rarely wipes every copy:

  1. Volume Shadow Copies. A shadow copy taken before the clearing holds the old .evtx files intact. Mount it, or let EvtxECmd process shadow copies directly. See the Volume Shadow Copies page.
  2. Carving EVTX chunks. Clearing creates a new file; the clusters of the old one are released, not wiped. Because each 64 KB ElfChnk chunk is self-describing, file carving of unallocated space (and of memory images, pagefile and hiberfil) can recover whole chunks. Tools such as EVTXtract (Willi Ballenthin) also try to rebuild individual records whose templates are missing.
  3. Archive files and forwarded copies. Look for Archive-*.evtx, SIEM data, EDR telemetry and backups.
  4. Other channels. Clearing Security does not touch PowerShell/Operational, TaskScheduler/Operational or Sysmon. Attackers often forget them.

Also check for tampering that avoids 1102: a stopped Event Log service (1100, or a gap between records without a reboot), jumps in EventRecordID, or a log whose first record starts long after the last boot. The dedicated anti-forensics guide goes further.

Tools

EvtxECmd

Eric Zimmerman's EvtxECmd parses EVTX into a normalized CSV. Its maps (one YAML per channel and event ID) extract the useful EventData fields into consistent columns such as UserName, RemoteHost and ExecutableInfo, which makes Timeline Explorer filtering fast.

# Update maps, then parse a folder of collected logs
EvtxECmd.exe --sync
EvtxECmd.exe -d E:\case\Logs --csv E:\out --csvf evtx.csv

# Only a few IDs, from a single file
EvtxECmd.exe -f E:\case\Logs\Security.evtx --csv E:\out --inc 4624,4625,4648,4672,4688

# Include shadow copies of a mounted volume, deduplicating records
EvtxECmd.exe -d F:\Windows\System32\winevt\Logs --vss --dedupe --csv E:\out

Hayabusa and Chainsaw

Both apply Sigma-style detection rules across a whole folder of logs in minutes, which makes them ideal first passes.

# Hayabusa: update rules, build a timeline, summarize logons
hayabusa update-rules
hayabusa csv-timeline -d ./Logs -o hayabusa.csv
hayabusa logon-summary -d ./Logs

# Chainsaw: Sigma hunt and keyword search
chainsaw hunt ./Logs -s sigma/ --mapping mappings/sigma-event-logs-all.yml -r rules/
chainsaw search mimikatz -i ./Logs

Treat their output as leads, not conclusions: rules fire on admin tooling, and a clean result only means no rule matched.

Get-WinEvent

Built-in, scriptable and fine for targeted questions on live or collected logs. Use -FilterHashtable or -FilterXPath so filtering happens in the API instead of piping everything through Where-Object.

# RDP and network logons in a time window, with key fields
$start = [datetime]'2026-09-20T00:00:00Z'
Get-WinEvent -FilterHashtable @{Path='E:\case\Logs\Security.evtx'; Id=4624; StartTime=$start} |
  ForEach-Object {
    $d = @{}; ([xml]$_.ToXml()).Event.EventData.Data | ForEach-Object { $d[$_.Name] = $_.'#text' }
    if ($d.LogonType -in '3','10') {
      [pscustomobject]@{ Time=$_.TimeCreated.ToUniversalTime(); User=$d.TargetUserName
        Type=$d.LogonType; Ip=$d.IpAddress; Workstation=$d.WorkstationName; LogonId=$d.TargetLogonId }
    }
  }

# Services installed, straight from the System log
Get-WinEvent -FilterHashtable @{LogName='System'; ProviderName='Service Control Manager'; Id=7045}

Common mistakes

  • Reading times in local time. TimeCreated is stored in UTC; Event Viewer and some exports display local time. Normalize to UTC before merging, as explained in UTC and local time.
  • Treating event IDs as global. An ID only means something together with its provider and channel: 4104 in PowerShell/Operational is unrelated to any other 4104.
  • Concluding absence from an empty result without checking audit policy and the oldest surviving record.
  • Trusting WorkstationName blindly. It is supplied by the client and can be spoofed or empty; prefer IpAddress and correlate with the source host.
  • Ignoring the small channels. TerminalServices, TaskScheduler, Defender and WMI-Activity often hold the only trace of an action.

A hunting workflow

  1. Collect every .evtx file (KAPE EventLogs target or Velociraptor), plus shadow copies, the SYSTEM and SOFTWARE hives and auditpol output if live. The acquisition and triage guide covers the collection side.
  2. Establish coverage: for each important log, note size, retention mode, oldest record and which audit categories were enabled.
  3. Look for tampering first: 1102, 104, 1100, 4719, record ID gaps.
  4. Run Hayabusa or Chainsaw for fast leads, then parse everything with EvtxECmd for the full picture.
  5. Scope authentication: 4624/4625 by logon type, source IP and account; 4648 and 4672; RDP 1149 and 21/24/25. Suspicious remote logons feed the lateral movement guide.
  6. Follow the session: chain TargetLogonId to 4688 or Sysmon 1, then to 4104, 7045, 4698 and Defender events. Persistence findings continue in hunting Windows persistence.
  7. Timeline: merge the parsed CSV with file system and registry artifacts in a super timeline, all in UTC.

Microsoft's audit policy recommendations are worth reading alongside your findings, both to know what should have been logged and to advise the client on what to turn on next time.

Area 03

Event Logs

The artifact cheat sheets behind this guide: location by Windows version, what each one proves and the tools to parse it.

Related articles