WINLOGBEAT
Winlogbeat is Elastic's lightweight shipper for Windows event logs. It reads the Windows Event Log API and forwards events to Elasticsearch or Logstash (often via the Elastic Agent in newer stacks, but Winlogbeat is still widely used). Config lives in winlogbeat.yml.
INSTALL & SERVICE (PowerShell, as admin)#
# From the extracted Winlogbeat folder: .\install-service-winlogbeat.ps1 install as a Windows service Start-Service winlogbeat Stop-Service winlogbeat Get-Service winlogbeat # Test config and output BEFORE starting the service: .\winlogbeat.exe test config -c .\winlogbeat.yml -e .\winlogbeat.exe test output -c .\winlogbeat.yml -e Default config path: C:\Program Files\winlogbeat\winlogbeat.yml
WHICH LOGS TO SHIP (winlogbeat.event_logs)#
winlogbeat.event_logs: - name: Security - name: System - name: Application - name: Microsoft-Windows-Sysmon/Operational - name: Microsoft-Windows-PowerShell/Operational - name: Windows PowerShell - name: Microsoft-Windows-TaskScheduler/Operational - name: Microsoft-Windows-Windows Defender/Operational - name: Microsoft-Windows-WMI-Activity/Operational - name: ForwardedEvents # if using Windows Event Collector/WEF These channel names match the Event Viewer "Full Name" of each log. Security, System, Sysmon, and PowerShell/Operational are the core SOC channels.
FILTERING EVENTS#
# Only specific Event IDs from a channel (comma list and ranges)
- name: Security
event_id: 4624, 4625, 4648, 4672, 4688, 4720, 4728, 4732, 1102
# Exclude noisy IDs
- name: Security
event_id: 4624, 4625, 4634
# or exclude with a leading minus:
# event_id: 1-5000, -4662
# By severity level (1 critical ... 4 info)
- name: Application
level: critical, error, warning
# Ignore events older than N when starting (first run catch-up control)
- name: System
ignore_older: 72h
PROCESSORS (enrich / trim at the edge)#
processors:
- add_host_metadata: ~ # host name, OS, IP
- add_fields:
target: ''
fields:
environment: production
site: dc1
- drop_event: # drop events you never want to ship
when:
equals:
winlog.event_id: "4634"
- drop_fields:
fields: ["event.original"] # trim raw XML to save space
Winlogbeat ships a security module that parses many Security events into
ECS fields (winlog.*, event.*, user.*, process.*), so downstream rules can
use normalized field names.
OUTPUT: ELASTICSEARCH#
output.elasticsearch:
hosts: ["https://es01:9200"]
protocol: "https"
username: "winlogbeat_writer"
password: "${ES_PWD}" # prefer the keystore (see below)
ssl.certificate_authorities: ["C:/certs/ca.crt"]
setup.kibana:
host: "https://kibana:5601"
OUTPUT: LOGSTASH (common when you need extra parsing/routing)#
output.logstash: hosts: ["logstash01:5044"] ssl.certificate_authorities: ["C:/certs/ca.crt"] ssl.certificate: "C:/certs/winlogbeat.crt" ssl.key: "C:/certs/winlogbeat.key" (Use EITHER elasticsearch OR logstash output, not both at once.)
SECRETS (keystore, keep passwords out of yml)#
.\winlogbeat.exe keystore create
.\winlogbeat.exe keystore add ES_PWD
.\winlogbeat.exe keystore list
# then reference ${ES_PWD} in winlogbeat.yml
DASHBOARDS / INDEX SETUP (one-time)#
.\winlogbeat.exe setup -e loads index template, ILM policy, and
Kibana dashboards (needs Kibana reachable)
COMMON ECS FIELDS AFTER INGEST#
winlog.channel source log (Security, System, Sysmon/Operational) winlog.event_id the Event ID (e.g. 4624) winlog.provider_name event provider winlog.computer_name host event.code event id (ECS) event.action normalized action name host.name host user.name account (where parsed) process.name / process.command_line (for 4688 / Sysmon 1) message rendered event text
TROUBLESHOOTING#
.\winlogbeat.exe test config -e config valid? .\winlogbeat.exe test output -e can it reach ES/Logstash? Get-Content "C:\ProgramData\winlogbeat\logs\winlogbeat" -Tail 50 its own log # No events arriving: # - service account lacks rights to read the Security log (needs admin / # "Event Log Readers" group membership). # - registry/journal position: delete the registry file only if you intend # to re-read from scratch (data\.winlogbeat.yml / registry path). # - output TLS/auth failing -> test output shows the error. # - firewall blocking 9200/5044 to the destination.
TIPS#
- Enable command-line auditing (4688) and Sysmon first, THEN ship them -- Winlogbeat only forwards what Windows actually records. - Filter at the edge (event_id / drop_event) to control volume and cost, but keep the high-value IDs (4624/4625/4648/4672/4688/4720/4728/4732/1102/7045). - Use ForwardedEvents + WEF to centralize first, then one Winlogbeat on the collector, when you cannot install an agent on every host.
WINLOGBEAT CHEATSHEET
=====================
Winlogbeat is Elastic's lightweight shipper for Windows event logs. It reads
the Windows Event Log API and forwards events to Elasticsearch or Logstash
(often via the Elastic Agent in newer stacks, but Winlogbeat is still widely
used). Config lives in winlogbeat.yml.
INSTALL & SERVICE (PowerShell, as admin)
----------------------------------------
# From the extracted Winlogbeat folder:
.\install-service-winlogbeat.ps1 install as a Windows service
Start-Service winlogbeat
Stop-Service winlogbeat
Get-Service winlogbeat
# Test config and output BEFORE starting the service:
.\winlogbeat.exe test config -c .\winlogbeat.yml -e
.\winlogbeat.exe test output -c .\winlogbeat.yml -e
Default config path: C:\Program Files\winlogbeat\winlogbeat.yml
WHICH LOGS TO SHIP (winlogbeat.event_logs)
------------------------------------------
winlogbeat.event_logs:
- name: Security
- name: System
- name: Application
- name: Microsoft-Windows-Sysmon/Operational
- name: Microsoft-Windows-PowerShell/Operational
- name: Windows PowerShell
- name: Microsoft-Windows-TaskScheduler/Operational
- name: Microsoft-Windows-Windows Defender/Operational
- name: Microsoft-Windows-WMI-Activity/Operational
- name: ForwardedEvents # if using Windows Event Collector/WEF
These channel names match the Event Viewer "Full Name" of each log. Security,
System, Sysmon, and PowerShell/Operational are the core SOC channels.
FILTERING EVENTS
----------------
# Only specific Event IDs from a channel (comma list and ranges)
- name: Security
event_id: 4624, 4625, 4648, 4672, 4688, 4720, 4728, 4732, 1102
# Exclude noisy IDs
- name: Security
event_id: 4624, 4625, 4634
# or exclude with a leading minus:
# event_id: 1-5000, -4662
# By severity level (1 critical ... 4 info)
- name: Application
level: critical, error, warning
# Ignore events older than N when starting (first run catch-up control)
- name: System
ignore_older: 72h
PROCESSORS (enrich / trim at the edge)
--------------------------------------
processors:
- add_host_metadata: ~ # host name, OS, IP
- add_fields:
target: ''
fields:
environment: production
site: dc1
- drop_event: # drop events you never want to ship
when:
equals:
winlog.event_id: "4634"
- drop_fields:
fields: ["event.original"] # trim raw XML to save space
Winlogbeat ships a security module that parses many Security events into
ECS fields (winlog.*, event.*, user.*, process.*), so downstream rules can
use normalized field names.
OUTPUT: ELASTICSEARCH
---------------------
output.elasticsearch:
hosts: ["https://es01:9200"]
protocol: "https"
username: "winlogbeat_writer"
password: "${ES_PWD}" # prefer the keystore (see below)
ssl.certificate_authorities: ["C:/certs/ca.crt"]
setup.kibana:
host: "https://kibana:5601"
OUTPUT: LOGSTASH (common when you need extra parsing/routing)
-------------------------------------------------------------
output.logstash:
hosts: ["logstash01:5044"]
ssl.certificate_authorities: ["C:/certs/ca.crt"]
ssl.certificate: "C:/certs/winlogbeat.crt"
ssl.key: "C:/certs/winlogbeat.key"
(Use EITHER elasticsearch OR logstash output, not both at once.)
SECRETS (keystore, keep passwords out of yml)
---------------------------------------------
.\winlogbeat.exe keystore create
.\winlogbeat.exe keystore add ES_PWD
.\winlogbeat.exe keystore list
# then reference ${ES_PWD} in winlogbeat.yml
DASHBOARDS / INDEX SETUP (one-time)
-----------------------------------
.\winlogbeat.exe setup -e loads index template, ILM policy, and
Kibana dashboards (needs Kibana reachable)
COMMON ECS FIELDS AFTER INGEST
------------------------------
winlog.channel source log (Security, System, Sysmon/Operational)
winlog.event_id the Event ID (e.g. 4624)
winlog.provider_name event provider
winlog.computer_name host
event.code event id (ECS)
event.action normalized action name
host.name host
user.name account (where parsed)
process.name / process.command_line (for 4688 / Sysmon 1)
message rendered event text
TROUBLESHOOTING
---------------
.\winlogbeat.exe test config -e config valid?
.\winlogbeat.exe test output -e can it reach ES/Logstash?
Get-Content "C:\ProgramData\winlogbeat\logs\winlogbeat" -Tail 50 its own log
# No events arriving:
# - service account lacks rights to read the Security log (needs admin /
# "Event Log Readers" group membership).
# - registry/journal position: delete the registry file only if you intend
# to re-read from scratch (data\.winlogbeat.yml / registry path).
# - output TLS/auth failing -> test output shows the error.
# - firewall blocking 9200/5044 to the destination.
TIPS
----
- Enable command-line auditing (4688) and Sysmon first, THEN ship them --
Winlogbeat only forwards what Windows actually records.
- Filter at the edge (event_id / drop_event) to control volume and cost, but
keep the high-value IDs (4624/4625/4648/4672/4688/4720/4728/4732/1102/7045).
- Use ForwardedEvents + WEF to centralize first, then one Winlogbeat on the
collector, when you cannot install an agent on every host.
Source: Elastic Winlogbeat reference (elastic.co/guide).
Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.