A fully automated, production-ready ELK + Grafana monitoring stack with Winlogbeat for comprehensive Windows Event Log monitoring. This project provides true one-click deployment using PowerShell and Docker, with dual installation modes for both full stack deployment and remote agent installation.
- π― True One-Click Setup: Single PowerShell command deploys the entire stack
- π Auto-Generated Credentials: Secure random passwords for all services
- π’ Dual Installation Modes:
- Full ELK Stack + Winlogbeat (Host Setup)
- Winlogbeat-only (Remote Agent Mode)
- π¦ Self-Contained: All configurations auto-generated - no manual editing required
- π Automated User Management: Elasticsearch users created and configured automatically
- π‘οΈ Production-Ready: Latest Elastic Stack 8.15.0 with security enabled
- π Pre-Integrated Grafana: Advanced dashboards with Elasticsearch datasource
- πͺ Windows Event Collection: Application, System, Security, and PowerShell logs
- π³ Fully Containerized: Complete isolation via Docker with health checks
- β‘ Optimized Performance: Proper memory allocation and restart policies
Before running the stack, ensure you have:
- Windows 10/11 or Windows Server 2019+
- PowerShell 5.1+ (Run as Administrator)
- Docker Desktop for Windows with WSL2 backend enabled
- Minimum 8GB RAM (16GB recommended for production)
- 10GB free disk space minimum
- Internet connection for Docker image downloads (first run only)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Windows Host System β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββ
β β Winlogbeat βββββΆβ Logstash βββββΆβElasticsearchββ
β β (Windows Service) β (Port 5044) β β (Port 9200) ββ
β β Event Collectorβ β Beat Processor β β Data Store ββ
β βββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββ
β β β
β βββββββββββββββββββ ββββββββββββββββββββ β β
β β Grafana β β Kibana βββββββββββ β
β β (Port 3000) β β (Port 5601) β β
β β Visualization β β Analytics UI β β
β βββββββββββββββββββ ββββββββββββββββββββ β
β β
β All services run in isolated Docker containers with auto- β
β restart policies and health monitoring β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Remote Agent Mode (Optional):
ββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ
β Remote Windows β β Central ELK Host β
β Machine β β β
β ββββββββββββββ β β ββββββββββββββββββββ β
β β Winlogbeat ββββΌββββββββββΆβ β Logstash β β
β β (Agent) β β Port β β (Port 5044) β β
β ββββββββββββββ β 5044 β ββββββββββββββββββββ β
ββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ
Perfect for setting up a central monitoring server.
# 1. Clone the repository
git clone https://github.com/SecByShresth/Windows-ELK-Monitoring-Stack.git
cd Windows-ELK-Monitoring-Stack
# 2. Run one-click setup as Administrator
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
.\oneclick-setup.ps1 -CleanInstall
# 3. Select Mode [1] when prompted
# Enter choice (1 or 2): 1What happens automatically:
- β Cleans any existing installation
- β Creates directory structure
- β
Generates secure
.envfile with random passwords - β
Creates
docker-compose.ymlwith optimized settings - β Configures Logstash pipeline for Winlogbeat
- β Starts Elasticsearch and waits for readiness
- β Sets up Elasticsearch users (kibana_system, logstash_system, winlogbeat_writer)
- β Starts Kibana, Logstash, and Grafana
- β Downloads and installs Winlogbeat 8.15.1
- β Registers Winlogbeat as Windows service
- β Displays all credentials and access URLs
Perfect for adding Windows machines to an existing ELK stack.
# 1. On the remote Windows machine
.\oneclick-setup.ps1 -CleanInstall
# 2. Select Mode [2] when prompted
# Enter choice (1 or 2): 2
# 3. Provide ELK host details
# Enter ELK Host IP or Domain: 192.168.1.100
# Enter Logstash Port (default: 5044): 5044What happens:
- β Installs Winlogbeat only (no Docker required)
- β Configures connection to remote ELK host
- β Registers and starts Winlogbeat service
- β Begins forwarding logs to central server
After successful setup, you'll see:
=========================================
ELK Stack Setup Complete!
=========================================
Access URLs:
Elasticsearch: http://localhost:9200
Kibana: http://localhost:5601
Grafana: http://localhost:3000
Logstash: localhost:5044 (Beats input)
Credentials:
Elasticsearch:
Username: elastic
Password: [16-char random password]
Kibana:
Username: elastic
Password: [same as Elasticsearch]
Grafana:
Username: admin
Password: [16-char random password]
Winlogbeat:
Username: winlogbeat_writer
Password: [16-char random password]
πΎ Save these credentials! They are also stored in elk-stack\.env
Windows-ELK-Monitoring-Stack/
βββ oneclick-setup.ps1 # β Main automation script (dual mode)
βββ README.md # This file
βββ LICENSE # MIT License
β
βββ elk-stack/ # Auto-generated during setup
βββ .env # Generated credentials
βββ docker-compose.yml # Generated Docker config
β
βββ elasticsearch/
β βββ data/ # Persistent data volume
β
βββ logstash/
β βββ pipeline/
β βββ winlogbeat.conf # Auto-generated pipeline
β
βββ kibana/
β βββ config/ # Kibana settings
β
βββ grafana/
β βββ data/ # Grafana data & dashboards
β
βββ winlogbeat/
βββ winlogbeat.yml # Auto-generated config
C:\Program Files\Winlogbeat/ # Installed by script
βββ winlogbeat.exe
βββ winlogbeat.yml
βββ logs/
The script creates .env with alphanumeric passwords (no special chars to avoid escaping issues):
# Elasticsearch Configuration
ELASTIC_VERSION=8.15.0
ELASTIC_PASSWORD=abc123XYZ789def4
ELASTIC_USERNAME=elastic
# Kibana Configuration
KIBANA_PASSWORD=xyz789ABC123ghi5
KIBANA_USERNAME=kibana_system
# Logstash Configuration
LOGSTASH_PASSWORD=def456GHI789jkl0
LOGSTASH_USERNAME=logstash_system
# Grafana Configuration
GRAFANA_VERSION=11.3.0
GRAFANA_PASSWORD=mno789PQR123stu6
GRAFANA_USERNAME=admin
# Winlogbeat Configuration
WINLOGBEAT_VERSION=8.15.1
WINLOGBEAT_PASSWORD=vwx012YZA345bcd7
WINLOGBEAT_USERNAME=winlogbeat_writer
# Network Configuration
ELASTICSEARCH_HOST=localhost
ELASTICSEARCH_PORT=9200
LOGSTASH_PORT=5044
KIBANA_PORT=5601
GRAFANA_PORT=3000- Security: Enabled with user authentication
- Memory: 2GB heap (configurable)
- Storage: Docker volume with full permissions
- Health Check: Automatic readiness verification
- Users: Auto-configured (elastic, kibana_system, logstash_system, winlogbeat_writer)
- Authentication: Uses kibana_system user
- Auto-restart: Restarts after password configuration
- Index Pattern: Works with winlogbeat-* indices
- Input: Beats protocol (Winlogbeat)
- Memory: 512MB heap
- Pipeline: Auto-configured for Windows Event Logs
- Output: Daily indices (winlogbeat-YYYY.MM.dd)
- No config file mount: Environment variables only (prevents read-only errors)
- Datasource: Elasticsearch (manual setup required)
- Persistent Storage: Docker volume
- Authentication: Admin user with random password
- Logs Collected:
- Application (errors, warnings, info)
- System (hardware, services, drivers)
- Security (authentication, authorization)
- PowerShell/Operational (script execution)
- Retention: Ignores events older than 72 hours
- Output: Logstash (Port 5044)
- Registry: C:/ProgramData/winlogbeat/.winlogbeat.yml
Auto-generated pipeline processes Windows Event Logs:
input {
beats {
port => 5044
ssl => false
}
}
filter {
# Creates daily indices
if [winlog] {
mutate {
add_field => { "[@metadata][target_index]" => "winlogbeat-%{+YYYY.MM.dd}" }
}
}
# Extracts event ID
if [event][code] {
mutate {
add_field => { "event_id" => "%{[event][code]}" }
}
}
# Parses timestamps
if [winlog][time_created] {
date {
match => [ "[winlog][time_created]", "ISO8601" ]
target => "@timestamp"
}
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
user => "elastic"
password => "${ELASTIC_PASSWORD}"
index => "%{[@metadata][target_index]}"
}
}cd elk-stack
docker-compose ps
# Should show all services as "Up" and "healthy"# All services
docker-compose logs -f
# Specific service
docker-compose logs -f elasticsearch
docker-compose logs -f kibana
docker-compose logs -f logstash
docker-compose logs -f grafana# Service status
Get-Service winlogbeat
# View logs
Get-Content "C:\ProgramData\winlogbeat\Logs\winlogbeat" -Tail 50 -Wait
# Restart service
Restart-Service winlogbeatcd elk-stack
# Stop all services
docker-compose down
# Start all services
docker-compose up -d
# Restart specific service
docker-compose restart kibana# Run script with clean install
.\oneclick-setup.ps1 -CleanInstall
# This removes:
# - All Docker containers and volumes
# - elk-stack directory
# - Winlogbeat service and installationError: Cannot connect to Docker daemon
Solution: Start Docker Desktop and ensure WSL2 backend is enabled
Elasticsearch container keeps restarting
Solution:
- Open Docker Desktop β Settings β Resources
- Increase Memory to 8GB minimum
- Apply & Restart
Error: Bind for 0.0.0.0:9200 failed: port is already allocated
Solution:
# Check what's using the port
Get-NetTCPConnection -LocalPort 9200
# Stop the conflicting service or change ports in elk-stack/.env# Check logs
cd elk-stack
docker-compose logs elasticsearch
# Common fix: Remove data and restart
docker-compose down -v
docker-compose up -d"failed to authenticate user [kibana_system]"
Solution: The script handles this automatically. If you see this:
# Manually set passwords
cd elk-stack
docker-compose restart elasticsearch
Start-Sleep 30
# Wait for ES to be ready, then restart dependent services
docker-compose restart kibana logstash# Check service
Get-Service winlogbeat
# If stopped, start it
Start-Service winlogbeat
# Check connectivity to Logstash
Test-NetConnection localhost -Port 5044
# View Winlogbeat logs for errors
Get-Content "C:\ProgramData\winlogbeat\Logs\winlogbeat" -Tail 100# Elasticsearch cluster health
Invoke-RestMethod -Uri "http://localhost:9200/_cluster/health" `
-Method Get `
-Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("elastic:YOUR_PASSWORD"))}
# Check for Winlogbeat indices
Invoke-RestMethod -Uri "http://localhost:9200/_cat/indices/winlogbeat*?v" `
-Method Get `
-Headers @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("elastic:YOUR_PASSWORD"))}
# Kibana status
Invoke-RestMethod -Uri "http://localhost:5601/api/status"
# Grafana health
Invoke-RestMethod -Uri "http://localhost:3000/api/health"- Access: http://localhost:5601
- Login: Use
elasticusername and password from setup output - Create Index Pattern:
- Go to Stack Management β Index Patterns
- Create pattern:
winlogbeat-* - Time field:
@timestamp
- Discover: View real-time logs with filters
- Dashboard: Create visualizations
Useful KQL Queries:
# Failed login attempts
event.code: 4625
# Application errors
log.level: "error" and winlog.channel: "Application"
# PowerShell execution
winlog.channel: "Microsoft-Windows-PowerShell/Operational"
# Events from last hour
@timestamp >= now-1h
- Access: http://localhost:3000
- Login:
admin/ (password from setup output) - Add Elasticsearch Datasource:
- Configuration β Data Sources β Add data source
- Select Elasticsearch
- URL:
http://elasticsearch:9200 - Auth: Basic Auth
- User:
elastic - Password: (from setup output)
- Index:
winlogbeat-* - Time field:
@timestamp
- Create Dashboards: Build custom visualizations
- β Elasticsearch security enabled
- β User authentication required
- β Randomly generated passwords
β οΈ HTTP only (no SSL/TLS)β οΈ Suitable for local development/testing
- Enable SSL/TLS on all services
- Use strong 32+ character passwords
- Implement role-based access control (RBAC)
- Enable audit logging
- Configure firewall rules (allow only necessary ports)
- Use separate networks for each tier
- Implement log retention policies
- Regular security updates
- Monitor for failed authentication attempts
- Backup Elasticsearch data regularly
Edit elk-stack/winlogbeat/winlogbeat.yml:
winlogbeat.event_logs:
- name: Application
- name: System
- name: Security
- name: Microsoft-Windows-PowerShell/Operational
- name: Microsoft-Windows-Sysmon/Operational # Sysmon logs
- name: Microsoft-Windows-DNS-Client/OperationalThen restart:
Restart-Service winlogbeatEdit elk-stack/docker-compose.yml:
# For Elasticsearch (default: 2g)
- "ES_JAVA_OPTS=-Xms4g -Xmx4g"
# For Logstash (default: 512m)
- LOGSTASH_JAVA_OPTS=-Xms1g -Xmx1gApply changes:
docker-compose down
docker-compose up -dEdit elk-stack/.env:
ELASTICSEARCH_PORT=9200
KIBANA_PORT=5601
GRAFANA_PORT=3000
LOGSTASH_PORT=5044Recreate containers:
docker-compose down
docker-compose up -d# Edit elk-stack/.env
ELASTIC_VERSION=8.16.0 # New version
# Pull new images and recreate
docker-compose pull
docker-compose down
docker-compose up -d# Stop service
Stop-Service winlogbeat
# Edit oneclick-setup.ps1
$Script:WinlogbeatVersion = "8.16.0"
# Re-run installation (Mode 1 or 2)
.\oneclick-setup.ps1Backup:
# Backup Elasticsearch data
docker-compose exec elasticsearch /usr/share/elasticsearch/bin/elasticsearch-snapshot
# Or backup the entire data directory
Copy-Item -Path "elk-stack\elasticsearch\data" -Destination "backup\es-data" -RecurseRestore:
# Stop services
docker-compose down
# Restore data
Copy-Item -Path "backup\es-data\*" -Destination "elk-stack\elasticsearch\data" -Recurse
# Start services
docker-compose up -d- Elasticsearch 8.15 Documentation
- Kibana 8.15 Documentation
- Logstash 8.15 Documentation
- Winlogbeat 8.15 Documentation
- Grafana Documentation
- Docker Compose Documentation
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Elastic for the comprehensive ELK Stack
- Grafana Labs for powerful visualization tools
- Docker for containerization technology
- Microsoft for Windows Event Logging infrastructure
- Community contributors for feedback and improvements
- π Check the Troubleshooting section
- π Search existing issues
- π¬ Ask questions in Discussions
Create a new issue with:
- Windows version
- Docker Desktop version
- PowerShell version
- Error messages
- Relevant logs (
docker-compose logs)
| Component | Version | Notes |
|---|---|---|
| Elasticsearch | 8.15.0 | Stable release |
| Kibana | 8.15.0 | Matched with ES |
| Logstash | 8.15.0 | Matched with ES |
| Winlogbeat | 8.15.1 | Latest stable |
| Grafana | 11.3.0 | Latest stable |
Tested on:
- Windows 10 21H2+
- Windows 11 22H2+
- Windows Server 2019
- Windows Server 2022
If this project helped you, please consider giving it a β!
Built with β€οΈ for Windows System Administrators, DevOps Engineers, and Security Professionals
Comprehensive Windows Event Log monitoring made simple and automated