Introduction to Log Analytics on Windows Server 2019

Azure Monitor Log Analytics is a cloud-hosted log management and analytics service that collects, stores, and analyzes log data from Windows Server 2019 and other sources. When Log Analytics is connected to Windows Server 2019, it ingests Windows Event Logs, performance counters, IIS logs, Syslog data, and custom log files into a central workspace where they can be queried using Kusto Query Language (KQL). Log Analytics enables powerful operational scenarios including security event analysis, performance trending, application troubleshooting, and compliance reporting across large numbers of servers from a single interface. Integration with Azure Sentinel extends Log Analytics into a full SIEM and SOAR platform for enterprise security operations.

Creating a Log Analytics Workspace

A Log Analytics workspace is the Azure resource that stores all collected log data. Create one using Azure CLI or the portal:

az login
az group create --name "Monitoring-RG" --location "eastus"
az monitor log-analytics workspace create 
  --resource-group "Monitoring-RG" 
  --workspace-name "CorpMonitoring" 
  --location "eastus" 
  --sku "PerGB2018" 
  --retention-time 90

Retrieve the workspace ID and key needed for agent configuration:

az monitor log-analytics workspace show --resource-group "Monitoring-RG" --workspace-name "CorpMonitoring" --query "customerId" -o tsv
az monitor log-analytics workspace get-shared-keys --resource-group "Monitoring-RG" --workspace-name "CorpMonitoring" --query "primarySharedKey" -o tsv

Installing the Log Analytics Agent on Windows Server 2019

The Microsoft Monitoring Agent (MMA) or the newer Azure Monitor Agent (AMA) collects data from Windows Server 2019 and sends it to Log Analytics. Install the MMA using PowerShell:

$workspaceId = "your-workspace-id"
$workspaceKey = "your-workspace-key"
$agentUri = "https://go.microsoft.com/fwlink/?LinkID=828603"
Invoke-WebRequest -Uri $agentUri -OutFile "$env:TEMPMMASetup-AMD64.exe"
& "$env:TEMPMMASetup-AMD64.exe" /C /T:$env:TEMPMMASetup
& "$env:TEMPMMASetupSetup.exe" /qn NOAPM=1 ADD_OPINSIGHTS_WORKSPACE=1 OPINSIGHTS_WORKSPACE_ID=$workspaceId OPINSIGHTS_WORKSPACE_KEY=$workspaceKey AcceptEndUserLicenseAgreement=1

Verify the agent installed and is connected:

Get-Service HealthService | Select-Object Status, DisplayName
Get-ItemProperty "HKLM:SOFTWAREMicrosoftMicrosoft Operations Manager3.0Agent Management Groups" | Select-Object *

Install the newer Azure Monitor Agent via PowerShell:

$params = @{
    Name           = "AzureMonitorWindowsAgent"
    Publisher      = "Microsoft.Azure.Monitor"
    Type           = "AzureMonitorWindowsAgent"
    TypeHandlerVersion = "1.0"
    AutoUpgradeMinorVersion = $true
    EnableAutomaticUpgrade = $true
}
Set-AzVMExtension @params -VMName "SERVER01" -ResourceGroupName "Servers-RG" -Location "eastus"

Configuring Data Collection Rules

With the Azure Monitor Agent, data collection is configured via Data Collection Rules (DCR) in Azure. DCRs define what data to collect and where to send it. Create a DCR for Windows event logs and performance counters:

az monitor data-collection rule create 
  --resource-group "Monitoring-RG" 
  --name "WS2019-DCR" 
  --location "eastus" 
  --data-flows '[{"streams":["Microsoft-Event","Microsoft-Perf"],"destinations":["CorpMonitoring"]}]' 
  --destinations '{"logAnalytics":[{"workspaceResourceId":"/subscriptions/sub-id/resourceGroups/Monitoring-RG/providers/Microsoft.OperationalInsights/workspaces/CorpMonitoring","name":"CorpMonitoring"}]}' 
  --data-sources '{"windowsEventLogs":[{"name":"eventLogsDataSource","streams":["Microsoft-Event"],"xPathQueries":["System!*[System[(Level=1 or Level=2 or Level=3)]]","Security!*[System[(band(Keywords,13510798882111488))]]"]}],"performanceCounters":[{"name":"perfCountersDataSource","streams":["Microsoft-Perf"],"samplingFrequencyInSeconds":60,"counterSpecifiers":["Processor(_Total)\% Processor Time","Memory\Available Bytes","LogicalDisk(_Total)\Disk Reads/sec","LogicalDisk(_Total)\Disk Writes/sec","Network Interface(*)\Bytes Total/sec"]}]}'

Configuring Windows Event Log Collection

Configure which Windows Event Logs to collect via the Log Analytics workspace portal or via the MMA agent configuration. For security-focused collection, include the Security, System, Application, and PowerShell Operational logs. Configure from the workspace settings in Azure portal under Agents configuration > Windows Event Logs. Using PowerShell for MMA workspace configuration:

$workspace = Get-AzOperationalInsightsWorkspace -ResourceGroupName "Monitoring-RG" -Name "CorpMonitoring"
$eventLogSources = @("System", "Application", "Security", "Microsoft-Windows-PowerShell/Operational", "Microsoft-Windows-TaskScheduler/Operational", "Microsoft-Windows-Windows Defender/Operational")
foreach ($logSource in $eventLogSources) {
    New-AzOperationalInsightsWindowsEventDataSource -ResourceGroupName "Monitoring-RG" -WorkspaceName "CorpMonitoring" -Name $logSource.Replace("/","_") -EventLogName $logSource -CollectErrors -CollectWarnings -CollectInformation
}

Querying Logs with KQL

Kusto Query Language (KQL) is used to query data in Log Analytics. Common queries for Windows Server 2019 monitoring. Find all failed logon events:

SecurityEvent
| where EventID == 4625
| where TimeGenerated > ago(24h)
| summarize FailedAttempts = count() by Account, IpAddress, Computer
| where FailedAttempts > 5
| order by FailedAttempts desc

Monitor Windows service failures:

Event
| where EventLog == "System"
| where EventID == 7034 or EventID == 7031 or EventID == 7036
| where TimeGenerated > ago(7d)
| project TimeGenerated, Computer, EventID, RenderedDescription
| order by TimeGenerated desc

Track CPU performance trends:

Perf
| where ObjectName == "Processor" and CounterName == "% Processor Time" and InstanceName == "_Total"
| where TimeGenerated > ago(1h)
| summarize AvgCPU = avg(CounterValue) by bin(TimeGenerated, 5m), Computer
| render timechart

Setting Up Alerts Based on Log Data

Create alert rules in Azure Monitor that trigger when specific conditions are met in the Log Analytics data. Create an alert for multiple failed logon attempts indicating a potential brute force attack:

az monitor scheduled-query create 
  --resource-group "Monitoring-RG" 
  --name "BruteForceAlert" 
  --scopes "/subscriptions/sub-id/resourceGroups/Monitoring-RG/providers/Microsoft.OperationalInsights/workspaces/CorpMonitoring" 
  --condition "count 'SecurityEvent | where EventID == 4625 | summarize count() by Computer' greater than 50" 
  --condition-query "SecurityEvent | where EventID == 4625 | summarize FailedAttempts = count() by Computer | where FailedAttempts > 50" 
  --evaluation-frequency 5m 
  --window-size 15m 
  --severity 2 
  --description "High number of failed logon attempts detected"

Configuring Log Retention and Archiving

Configure log retention in the Log Analytics workspace. The default retention is 30 days for free tier and up to 730 days for paid tiers. Data beyond the retention period can be archived to Azure Storage for long-term compliance storage:

az monitor log-analytics workspace update 
  --resource-group "Monitoring-RG" 
  --workspace-name "CorpMonitoring" 
  --retention-time 365

az storage account create 
  --name "corplogarchive" 
  --resource-group "Monitoring-RG" 
  --location "eastus" 
  --sku "Standard_LRS"

az monitor log-analytics workspace data-export create 
  --resource-group "Monitoring-RG" 
  --workspace-name "CorpMonitoring" 
  --name "SecurityLogExport" 
  --tables SecurityEvent Event Perf 
  --destination "/subscriptions/sub-id/resourceGroups/Monitoring-RG/providers/Microsoft.Storage/storageAccounts/corplogarchive"

Verifying Log Collection

Verify that Windows Server 2019 is sending data to Log Analytics by running a heartbeat query and checking for recent data:

# Run in Log Analytics Query editor
Heartbeat
| where Computer == "SERVER01"
| order by TimeGenerated desc
| take 5

# Check last data received time
Heartbeat
| summarize LastSeen = max(TimeGenerated) by Computer
| where LastSeen < ago(1h)
# No results means all agents are reporting within the last hour

Check agent health from Windows Server 2019:

Get-Service HealthService | Select-Object Status
Test-NetConnection -ComputerName "ods.opinsights.azure.com" -Port 443
Get-EventLog -LogName "Operations Manager" -Source "Health Service" -Newest 10 | Select-Object TimeGenerated, Message