How to Set Up Log Analytics with Windows Event Logs on Windows Server 2022

Log Analytics, part of Azure Monitor, provides a centralized repository for log data from Windows Server 2022 environments alongside a powerful query engine based on the Kusto Query Language (KQL). This guide covers the full process from creating a workspace to writing production-quality queries over Windows Event Log data, setting up alerts, and managing data retention.

Creating a Log Analytics Workspace

A Log Analytics workspace is an Azure resource that stores collected log data and provides the query interface. All data collected from Windows servers flows into this workspace and is stored according to the configured retention period. Each workspace has its own identity and access controls, and an organization may operate multiple workspaces for regulatory data separation or geographic proximity.

Create a workspace using the Azure CLI:


# Create a resource group if it does not exist
az group create --name rg-logging --location eastus

# Create the Log Analytics workspace
az monitor log-analytics workspace create 
  --resource-group rg-logging 
  --workspace-name law-windows-prod 
  --location eastus 
  --sku PerGB2018 
  --retention-time 90

# Retrieve the workspace ID and primary key (needed for agent registration)
az monitor log-analytics workspace show 
  --resource-group rg-logging 
  --workspace-name law-windows-prod 
  --query "{WorkspaceID:customerId, Sku:sku, RetentionDays:retentionInDays}" -o table

az monitor log-analytics workspace get-shared-keys 
  --resource-group rg-logging 
  --workspace-name law-windows-prod 
  --query "primarySharedKey" -o tsv

The PerGB2018 pricing tier charges per gigabyte of data ingested beyond 5 GB per day (which is free). For high-volume environments, Commitment Tiers (100 GB/day, 200 GB/day, etc.) offer significant discounts. Retention defaults to 30 days for most tables; extending to 90 days or more incurs additional storage costs but enables longer historical analysis.

Connecting Windows Server 2022 Using Azure Monitor Agent

The Azure Monitor Agent (AMA) replaces the legacy Log Analytics Agent (MMA) as the recommended method for connecting Windows Server 2022. AMA requires a Data Collection Rule to specify which event channels and performance counters to send. For servers running in Azure, install AMA as a VM extension. For on-premises servers, connect via Azure Arc first.

Install AMA on an Azure VM using PowerShell:


# Install AMA on an Azure VM
Set-AzVMExtension `
  -ResourceGroupName "rg-servers" `
  -VMName "WinServer2022-01" `
  -Name "AzureMonitorWindowsAgent" `
  -Publisher "Microsoft.Azure.Monitor" `
  -ExtensionType "AzureMonitorWindowsAgent" `
  -TypeHandlerVersion "1.0" `
  -Location "eastus" `
  -EnableAutomaticUpgrade $true

For environments still using the legacy MMA (Log Analytics Agent), the workspace ID and key are used directly during installation:


# MMA silent install (for legacy deployments - migrate to AMA when possible)
$workspaceId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$workspaceKey = "base64encodedprimarykey=="
$mmaInstaller = "MMASetup-AMD64.exe"

# Download MMA installer
Invoke-WebRequest -Uri "https://download.microsoft.com/download/1/5/E/15E274B9-F9E2-42AE-86EC-AC988F0DC9D4/MMASetup-AMD64.exe" `
  -OutFile "C:Temp$mmaInstaller"

# Silent install with workspace connection
Start-Process -FilePath "C:Temp$mmaInstaller" `
  -ArgumentList "/Q:A /R:N /C:`"setup.exe /qn ADD_OPINSIGHTS_WORKSPACE=1 OPINSIGHTS_WORKSPACE_ID=$workspaceId OPINSIGHTS_WORKSPACE_KEY=$workspaceKey AcceptEndUserLicenseAgreement=1`"" `
  -Wait

# Verify MMA service is running
Get-Service -Name HealthService | Select-Object Name, Status, StartType

Configuring Windows Event Log Collection Channels

When using AMA, Windows Event Log collection is configured in the Data Collection Rule as XPath queries that precisely select which events to ingest. XPath queries allow filtering at collection time, reducing ingestion costs by excluding low-value noise before data reaches the workspace.

A DCR definition for comprehensive Windows Event Log collection from Application, System, and Security channels:


{
  "dataSources": {
    "windowsEventLogs": [
      {
        "name": "ApplicationChannel",
        "streams": ["Microsoft-Event"],
        "xPathQueries": [
          "Application!*[System[(Level=1 or Level=2 or Level=3)]]"
        ]
      },
      {
        "name": "SystemChannel",
        "streams": ["Microsoft-Event"],
        "xPathQueries": [
          "System!*[System[(Level=1 or Level=2 or Level=3)]]"
        ]
      },
      {
        "name": "SecurityChannel",
        "streams": ["Microsoft-Event"],
        "xPathQueries": [
          "Security!*[System[(EventID=4624 or EventID=4625 or EventID=4634 or EventID=4647 or EventID=4648 or EventID=4656 or EventID=4663 or EventID=4688 or EventID=4720 or EventID=4726 or EventID=4732 or EventID=4756)]]"
        ]
      }
    ]
  }
}

For the legacy MMA, event channels are configured on the workspace itself under Legacy Agents Management > Windows Event Logs. You select channels from a dropdown and choose Error, Warning, and Information severity levels. This workspace-level configuration applies to all connected MMA agents uniformly, unlike the per-machine precision of DCRs.

Collecting Custom Windows Event Log Channels

Many Windows Server roles and applications write to custom event log channels beyond the standard Application, System, and Security channels. Examples include Microsoft-Windows-DNS-Server/Audit, Microsoft-Windows-TaskScheduler/Operational, and application-specific logs like Microsoft-Windows-IIS-Logging/Logs.

To collect a custom channel, first identify the exact channel name using PowerShell:


# List all event log channels on the server
Get-WinEvent -ListLog * | Where-Object { $_.IsEnabled -eq $true } | Select-Object LogName, RecordCount, MaximumSizeInBytes | Sort-Object RecordCount -Descending

# Find DNS Server audit log
Get-WinEvent -ListLog "Microsoft-Windows-DNS-Server/Audit" | Select-Object LogName, IsEnabled, RecordCount

# Verify Task Scheduler operational log
Get-WinEvent -ListLog "Microsoft-Windows-TaskScheduler/Operational" | Select-Object LogName, IsEnabled

Add the custom channel to the DCR XPath queries:


{
  "name": "DNSAuditChannel",
  "streams": ["Microsoft-Event"],
  "xPathQueries": [
    "Microsoft-Windows-DNS-Server/Audit!*"
  ]
}

Using the Log Analytics Query Editor with KQL

The Log Analytics query editor in the Azure portal provides a full IDE for writing KQL queries with IntelliSense, syntax highlighting, and built-in schema exploration. Navigate to Monitor > Log Analytics Workspaces > your workspace > Logs to access it. The left panel shows tables grouped by category. The Event table contains Windows Event Logs, the Perf table contains performance counters, and the Heartbeat table tracks agent connectivity.

The Event table schema includes these important columns:


// Explore Event table schema
Event
| getschema
| project ColumnName, DataType, Description

// Key Event table columns:
// TimeGenerated    - datetime  - When the event was generated
// Computer         - string    - Server hostname
// Source           - string    - Event source (application name)
// EventID          - int       - Windows Event ID
// EventCategory    - string    - Category name
// EventLevelName   - string    - Information / Warning / Error / Critical
// EventLevel       - int       - 0=LogAlways, 1=Critical, 2=Error, 3=Warning, 4=Information
// UserName         - string    - User context of the event
// RenderedDescription - string - Full formatted event message
// ParameterXml     - string    - Raw event parameters in XML
// MG               - string    - Management group identifier

Querying Specific Event IDs

Security monitoring on Windows Server 2022 relies heavily on specific Event IDs from the Security channel. Event ID 4625 represents a failed logon attempt. Analyzing the frequency, source, and target accounts of these events identifies brute-force attacks, misconfigured service accounts, and credential stuffing attempts.


// Failed logon attempts - Event ID 4625
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4625
| project TimeGenerated, Computer, Account, AccountType, LogonType, IpAddress, IpPort, SubStatus
| summarize FailureCount = count() by Computer, Account, IpAddress, bin(TimeGenerated, 1h)
| where FailureCount > 10
| order by FailureCount desc

// If using the Event table instead of SecurityEvent (AMA without Sentinel)
Event
| where TimeGenerated > ago(24h)
| where EventID == 4625 and EventLog == "Security"
| extend AccountName = extract(@"Account Name:s+(S+)r?n", 1, RenderedDescription)
| extend IpAddress = extract(@"Source Network Address:s+(S+)r?n", 1, RenderedDescription)
| extend LogonType = extract(@"Logon Type:s+(d+)", 1, RenderedDescription)
| summarize Failures = count() by Computer, AccountName, IpAddress, LogonType
| where Failures > 5
| order by Failures desc

Track privilege escalation attempts using Event ID 4672 (special privileges assigned to new logon):


// Privileged logons - Event ID 4672
Event
| where TimeGenerated > ago(7d)
| where EventID == 4672 and EventLog == "Security"
| extend AccountName = extract(@"Account Name:s+(S+)r?n", 1, RenderedDescription)
| extend Privileges = extract(@"Privileges:s+(.+)", 1, RenderedDescription)
| where AccountName !endswith "$"  // Exclude computer accounts
| where AccountName !in ("SYSTEM", "LOCAL SERVICE", "NETWORK SERVICE")
| summarize LogonCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by Computer, AccountName
| order by LogonCount desc

Creating Saved Queries and Alerts from Log Analytics

Saved queries allow teams to maintain a library of validated KQL queries accessible to all workspace users. Save a query from the query editor by clicking Save > Save as query and providing a category and name. Saved queries appear in the query explorer panel and can be referenced by name.

Create a log search alert from a query that detects Windows service crashes:


// Query to detect service control manager errors (Event ID 7031 = service terminated unexpectedly)
Event
| where TimeGenerated > ago(5m)
| where EventID == 7031 and Source == "Service Control Manager"
| extend ServiceName = extract(@"The (.+?) service terminated unexpectedly", 1, RenderedDescription)
| project TimeGenerated, Computer, ServiceName, RenderedDescription

Create the alert rule via Azure CLI:


az monitor scheduled-query create 
  --resource-group rg-logging 
  --name "alert-service-crash" 
  --scopes "/subscriptions//resourceGroups/rg-logging/providers/Microsoft.OperationalInsights/workspaces/law-windows-prod" 
  --condition-query "Event | where TimeGenerated > ago(5m) | where EventID == 7031 and Source == 'Service Control Manager'" 
  --condition-time-aggregation Count 
  --condition-operator GreaterThan 
  --condition-threshold 0 
  --evaluation-frequency 5m 
  --window-size 5m 
  --severity 1 
  --description "Windows service terminated unexpectedly" 
  --action-groups "/subscriptions//resourceGroups/rg-logging/providers/Microsoft.Insights/actionGroups/ag-windows-ops"

Exporting Query Results and Managing Retention

Query results can be exported to CSV from the portal query editor, or streamed continuously to a Storage Account or Event Hub using Log Analytics data export rules. Data export is useful for feeding data to SIEM systems or long-term cold storage archives.


# Create a data export rule to export the Event table to Azure Storage
az monitor log-analytics workspace data-export create 
  --resource-group rg-logging 
  --workspace-name law-windows-prod 
  --name export-event-table 
  --tables Event 
  --destination "/subscriptions//resourceGroups/rg-logging/providers/Microsoft.Storage/storageAccounts/stlogarchive001" 
  --enable true

Adjust per-table retention to keep security events longer than general logs:


# Set SecurityEvent table retention to 365 days
az monitor log-analytics workspace table update 
  --resource-group rg-logging 
  --workspace-name law-windows-prod 
  --name SecurityEvent 
  --retention-time 365

# Set Event table retention to 90 days
az monitor log-analytics workspace table update 
  --resource-group rg-logging 
  --workspace-name law-windows-prod 
  --name Event 
  --retention-time 90

# Check current table retention settings
az monitor log-analytics workspace table list 
  --resource-group rg-logging 
  --workspace-name law-windows-prod 
  --query "[].{Table:name, RetentionDays:retentionInDays, TotalRetentionDays:totalRetentionInDays}" -o table

Data beyond the interactive retention period but within the total retention period moves to long-term low-cost archive storage and can still be queried via search jobs or restored to the hot tier on demand. This two-tier retention model allows organizations to meet compliance requirements for multi-year log retention without paying full hot-tier prices for old data.