Introduction to Azure Monitor for Windows Server 2019

Azure Monitor is Microsoft’s comprehensive monitoring service that collects, analyzes, and acts on telemetry from cloud and on-premises environments. When configured for Windows Server 2019, Azure Monitor provides real-time metrics, log analytics, alerting, dashboards, and automated responses to operational conditions. Azure Monitor VM Insights provides pre-built workbooks showing CPU utilization, memory, disk I/O, network traffic, and top processes with minimal configuration. Combined with Azure Monitor Alerts, you can receive notifications via email, SMS, Azure Functions, Logic Apps, or webhooks when thresholds are exceeded. This guide covers the complete configuration of Azure Monitor for on-premises Windows Server 2019 machines using the Azure Monitor Agent and VM Insights.

Prerequisites and Architecture

Azure Monitor for on-premises Windows Server 2019 requires an Azure subscription, a Log Analytics workspace, and a Data Collection Rule. The Azure Monitor Agent (AMA) is the recommended agent for new deployments, replacing the older Log Analytics Agent (MMA) and Dependency Agent. For VM Insights service map functionality, the Dependency Agent must also be installed alongside AMA. Ensure the server has outbound HTTPS access to Azure Monitor endpoints including *.ods.opinsights.azure.com, *.oms.opinsights.azure.com, and dc.services.visualstudio.com on port 443. If the server is connected to Azure Arc, AMA deployment is simplified through Arc extension management.

Test-NetConnection -ComputerName "global.handler.control.monitor.azure.com" -Port 443
Test-NetConnection -ComputerName "your-workspace-id.ods.opinsights.azure.com" -Port 443

Connecting Windows Server 2019 to Azure Arc

For the cleanest Azure Monitor integration, first connect Windows Server 2019 to Azure Arc which enables managing monitor agents through the Azure portal. Install the Azure Connected Machine agent:

$servicePrincipalId = "your-sp-id"
$servicePrincipalSecret = "your-sp-secret"
$subscriptionId = "your-sub-id"
$resourceGroup = "Monitoring-RG"
$tenantId = "your-tenant-id"
$location = "eastus"
$workspaceName = "CorpMonitoring"

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri "https://aka.ms/azcmagent-windows" -OutFile "$env:TEMPinstall_azcmagent.ps1"
& "$env:TEMPinstall_azcmagent.ps1"

& "C:Program FilesAzureConnectedMachineAgentazcmagent.exe" connect --service-principal-id $servicePrincipalId --service-principal-secret $servicePrincipalSecret --resource-group $resourceGroup --tenant-id $tenantId --location $location --subscription-id $subscriptionId

Installing the Azure Monitor Agent

Install the Azure Monitor Agent on the Arc-connected Windows Server 2019 machine using Azure CLI:

az connectedmachine extension create 
  --machine-name "SERVER01" 
  --resource-group "Monitoring-RG" 
  --name "AzureMonitorWindowsAgent" 
  --type "AzureMonitorWindowsAgent" 
  --publisher "Microsoft.Azure.Monitor" 
  --type-handler-version "1.2" 
  --location "eastus" 
  --auto-upgrade-minor-version true

Verify the agent extension is installed and running:

az connectedmachine extension show --machine-name "SERVER01" --resource-group "Monitoring-RG" --name "AzureMonitorWindowsAgent" --query "provisioningState" -o tsv
Get-Service AzureMonitorAgent | Select-Object Status, DisplayName

Creating a Data Collection Rule for VM Insights

VM Insights requires a specific Data Collection Rule that collects performance counters and event log data needed to populate the pre-built workbooks. Create the DCR from the Azure portal by navigating to Monitor > Settings > Data Collection Rules and selecting the VM Insights preset, or create it manually:

az monitor data-collection rule create 
  --resource-group "Monitoring-RG" 
  --name "VMInsights-DCR" 
  --location "eastus" 
  --data-flows '[{"streams":["Microsoft-InsightsMetrics","Microsoft-Perf","Microsoft-Event"],"destinations":["CorpMonitoring"]}]' 
  --destinations '{"logAnalytics":[{"workspaceResourceId":"/subscriptions/sub-id/resourceGroups/Monitoring-RG/providers/Microsoft.OperationalInsights/workspaces/CorpMonitoring","name":"CorpMonitoring"}]}' 
  --data-sources '{
    "performanceCounters": [{
      "name": "VMInsightsPerfCounters",
      "streams": ["Microsoft-InsightsMetrics"],
      "samplingFrequencyInSeconds": 60,
      "counterSpecifiers": [
        "\VmInsights\DetailedMetrics",
        "\Processor(_Total)\% Processor Time",
        "\Memory\% Committed Bytes In Use",
        "\Memory\Available Bytes",
        "\LogicalDisk(*)\% Free Space",
        "\LogicalDisk(*)\Avg. Disk sec/Read",
        "\LogicalDisk(*)\Avg. Disk sec/Write",
        "\Network Interface(*)\Bytes Total/sec"
      ]
    }]
  }'

Installing the Dependency Agent for Service Map

The Dependency Agent extends VM Insights by collecting network connection data and process dependency information, enabling the Service Map feature that visualizes application dependencies. Install the Dependency Agent extension on Arc-connected machines:

az connectedmachine extension create 
  --machine-name "SERVER01" 
  --resource-group "Monitoring-RG" 
  --name "DependencyAgentWindows" 
  --type "DependencyAgentWindows" 
  --publisher "Microsoft.Azure.Monitoring.DependencyAgent" 
  --type-handler-version "9.10" 
  --location "eastus"

Verify Dependency Agent service is running:

Get-Service "Microsoft Dependency Agent" | Select-Object Status, DisplayName

Configuring Azure Monitor Metrics

Azure Monitor collects platform metrics automatically for Azure resources, but for on-premises servers, metrics flow through the Log Analytics workspace. Configure custom metrics collection by adding a custom performance counter data source to your DCR. After the agent is collecting data, query metrics in Log Analytics:

# CPU utilization over the last hour
InsightsMetrics
| where Name == "utilization" and Namespace == "Processor"
| where Computer == "SERVER01"
| where TimeGenerated > ago(1h)
| project TimeGenerated, Computer, Val
| render timechart

# Memory available bytes
InsightsMetrics
| where Name == "availableBytes" and Namespace == "Memory"
| where Computer == "SERVER01"
| where TimeGenerated > ago(1h)
| summarize AvgMemory = avg(Val) by bin(TimeGenerated, 5m)
| render timechart

Creating Azure Monitor Dashboards

Build custom Azure dashboards to visualize Windows Server 2019 health at a glance. Pin charts from Log Analytics queries to a shared dashboard. Create a dashboard using Azure CLI:

az portal dashboard create 
  --resource-group "Monitoring-RG" 
  --name "WS2019-Operations" 
  --location "eastus" 
  --input-path "C:DashboardsServerDashboard.json"

Add a tile from the portal by running a Log Analytics query, then clicking Pin to Dashboard and selecting the dashboard. Common tiles to include: CPU utilization trend (line chart), available memory (gauge), disk free space (table), top processes by CPU (table), failed logon events (count tile), and Windows service failures (alert count).

Configuring Metric Alerts

Create metric-based alerts that trigger when performance thresholds are exceeded. Create alerts for high CPU and low disk space on the Windows Server 2019 machine:

az monitor metrics alert create 
  --resource-group "Monitoring-RG" 
  --name "HighCPU-SERVER01" 
  --scopes "/subscriptions/sub-id/resourceGroups/Monitoring-RG/providers/Microsoft.HybridCompute/machines/SERVER01" 
  --condition "avg percentage cpu > 90" 
  --window-size 5m 
  --evaluation-frequency 1m 
  --severity 2 
  --description "CPU above 90% for 5 minutes" 
  --action "/subscriptions/sub-id/resourceGroups/Monitoring-RG/providers/microsoft.insights/actionGroups/OpTeamAlerts"

Create a log-based alert for low disk space using Log Analytics:

az monitor scheduled-query create 
  --resource-group "Monitoring-RG" 
  --name "LowDiskSpace" 
  --scopes "/subscriptions/sub-id/resourceGroups/Monitoring-RG/providers/Microsoft.OperationalInsights/workspaces/CorpMonitoring" 
  --condition-query "InsightsMetrics | where Namespace == 'LogicalDisk' and Name == 'freeSpacePercentage' | where Val < 10 | project Computer, Val" 
  --condition "count 'InsightsMetrics | where Namespace == ''LogicalDisk'' and Name == ''freeSpacePercentage'' | where Val < 10' greater than 0" 
  --evaluation-frequency 15m 
  --window-size 15m 
  --severity 1 
  --description "Disk free space below 10%"

Creating Action Groups for Alert Notifications

Action groups define what happens when an alert fires. Configure email, SMS, and webhook notifications:

az monitor action-group create 
  --resource-group "Monitoring-RG" 
  --name "OpTeamAlerts" 
  --short-name "OpTeam" 
  --action email ops-lead "[email protected]" 
  --action email ops-team "[email protected]" 
  --action sms phone1 1 5555551234 
  --action webhook PagerDuty "https://events.pagerduty.com/integration/xxxxx/enqueue"

Verify Azure Monitor data collection is working by checking recent heartbeat data from the server:

# Run in Azure Monitor Log Analytics
Heartbeat
| where Computer == "SERVER01"
| summarize LastHeartbeat = max(TimeGenerated)
| project Computer = "SERVER01", LastHeartbeat, MinutesSinceLastHeartbeat = datetime_diff('minute', now(), LastHeartbeat)