Introduction to Log Analytics with Windows Event Logs

Centralizing Windows Event Logs in Azure Log Analytics (part of Azure Monitor) transforms raw event data into a searchable, queryable, and alertable intelligence source. Windows Server 2019 generates thousands of events per day across the Application, Security, System, and application-specific event logs. Without centralization, these logs are isolated on each server and often overwritten after a few days. Log Analytics provides long-term retention (up to 2 years), cross-server correlation, and powerful Kusto Query Language (KQL) analysis capabilities. This guide walks through configuring Windows Event Log collection via the Azure Monitor Agent’s Data Collection Rules, designing effective KQL queries for security and operational analysis, and setting up log-based alerts.

Choosing Which Event Logs to Collect

Collecting every event from every log creates excessive cost and noise. Plan your collection strategy based on operational and security requirements:

Security log (always collect): Critical for security monitoring. Recommended Event IDs: 4624 (successful logon), 4625 (failed logon), 4648 (logon with explicit credentials), 4720 (user account created), 4732 (member added to security group), 4756 (member added to universal security group), 4771 (Kerberos preauthentication failed), 4776 (NTLM authentication), 4798/4799 (local group membership query), 7045 (new service installed), 1102 (audit log cleared).

System log (collect warnings and errors): Event ID 41 (kernel power failure/unexpected shutdown), 1001 (Windows error reporting/BSOD), 7023/7034 (service stopped unexpectedly), 6005/6006 (event log started/stopped, indicates restarts).

Application log (collect errors): Application-specific errors and crashes. At minimum collect Error and Critical severity events.

Directory Service log (domain controllers only): Events related to AD replication, LDAP, and Kerberos.

Configuring Event Log Collection via Data Collection Rule

Data Collection Rules (DCR) define which Windows Event Logs are collected and forwarded to a Log Analytics Workspace. In the Azure Portal, navigate to Monitor > Data Collection Rules > Create (or edit an existing DCR). On the Collect and Deliver tab, add a Windows Event Logs data source.

In the Basic configuration mode, select the event channels (Application, Security, System, Microsoft-Windows-PowerShell/Operational, etc.) and severity levels. For fine-grained control, switch to Custom (XPath queries) mode. XPath queries allow you to filter specific Event IDs, reducing ingestion volume and cost:

Security!*[System[(EventID=4624 or EventID=4625 or EventID=4648 or EventID=4720 or EventID=4726 or EventID=4732 or EventID=4756)]]
System!*[System[(Level=1 or Level=2 or Level=3) and (EventID=41 or EventID=7023 or EventID=7034 or EventID=1001 or EventID=6005 or EventID=6006)]]
Application!*[System[(Level=1 or Level=2)]]

Set the destination to your Log Analytics Workspace and save the DCR. Events from associated Windows Server 2019 machines begin flowing to the workspace within minutes.

Querying Windows Event Logs in Log Analytics

Windows Event Logs collected by AMA appear in the Event table (for Application, System, and custom logs) and the SecurityEvent table (for the Security log) in Log Analytics. Open Azure Monitor > Logs and select your workspace to start writing KQL.

Find failed logon attempts in the past 24 hours, grouped by account and source IP:

SecurityEvent
| where EventID == 4625
| where TimeGenerated > ago(24h)
| extend AccountName = tostring(split(Account, "\")[1])
| summarize FailedAttempts = count() by AccountName, IpAddress, Computer
| where FailedAttempts > 5
| order by FailedAttempts desc

Detect accounts that logged on after hours (defined as 8 PM to 6 AM local time, adjust UTC offset as needed):

SecurityEvent
| where EventID == 4624
| where TimeGenerated > ago(7d)
| extend Hour = datetime_part("Hour", TimeGenerated)
| where Hour >= 20 or Hour <= 6
| project TimeGenerated, Computer, Account, IpAddress, LogonType
| order by TimeGenerated desc

Find the top event sources generating errors in the Application log:

Event
| where EventLog == "Application" and EventLevelName == "Error"
| where TimeGenerated > ago(7d)
| summarize ErrorCount = count() by Source, Computer
| order by ErrorCount desc
| take 20

Detect new services installed on any monitored server (potential persistence mechanism):

SecurityEvent
| where EventID == 7045
| where TimeGenerated > ago(30d)
| project TimeGenerated, Computer, EventData
| order by TimeGenerated desc

Setting Up Saved Searches and Alerts

Save frequently used KQL queries in Log Analytics as Saved Searches for quick access. In the Logs editor, after writing a query, click Save > Save as query. Assign a category (Operations, Security, etc.) and a name. Saved queries appear in the Query Explorer panel on the right side of the Logs interface.

Create a log search alert from within the Log Analytics Logs view. Write the detection query — for example, detecting when more than 10 failed logon attempts occur within 5 minutes for any single account:

SecurityEvent
| where EventID == 4625
| where TimeGenerated >= ago(5m)
| summarize count() by Account
| where count_ > 10

Click New Alert Rule above the query editor. Set the evaluation frequency to every 5 minutes, the aggregation granularity (lookback period) to 5 minutes, and the threshold to Greater than 0 results (meaning the query returns any rows). Assign an Action Group for email notification. This creates a brute-force detection alert covering all monitored Windows Server 2019 machines simultaneously.

Exporting Log Data for SIEM Integration

For organizations running a SIEM (Security Information and Event Management) platform, Log Analytics can forward data to Azure Sentinel (Microsoft Sentinel), which is natively integrated. For third-party SIEMs, use the Log Analytics data export feature to continuously export data to Azure Storage Account or Azure Event Hub, from which the SIEM can ingest via its Azure connector.

Configure data export via Azure PowerShell:

New-AzOperationalInsightsDataExport -ResourceGroupName "monitoring-rg" -WorkspaceName "ws2019-monitoring-law" -DataExportName "SecurityEvents-Export" -TableName @("SecurityEvent", "Event") -EventHubNamespace "siem-eventhub-ns" -Enable $true

This continuously exports SecurityEvent and Event table data to an Event Hub where your SIEM (Splunk, QRadar, etc.) can consume it using its Azure Event Hub connector plugin.

Managing Log Analytics Costs

Log Analytics pricing is based on data ingestion and retention. Use the Usage and Estimated Costs blade in the Log Analytics Workspace to review daily ingestion volumes per table. The SecurityEvent table is typically the largest for Windows environments. To reduce Security log ingestion without losing important events, use XPath-based filtering to drop high-volume noise events such as Event ID 4688 (process creation) unless you specifically need process audit logging.

Query ingestion usage by table:

Usage
| where TimeGenerated > ago(30d)
| summarize IngestedGB = sum(Quantity)/1024 by DataType
| order by IngestedGB desc

Consider Commitment Tiers if your daily ingestion exceeds 100 GB — commitment tiers offer significant per-GB discounts over the Pay-As-You-Go rate. Use archive tiers for data older than 30 days that you need to retain for compliance but rarely query.