Task 04: Enable Security Logging
DOCUMENT CATEGORY: Runbook SCOPE: Security event collection PURPOSE: Configure Data Collection Rules for security logs MASTER REFERENCE: Microsoft Learn - DCR
Status: Active
Security logging provides visibility into security events across your Azure Local infrastructure. This step configures Data Collection Rules (DCR) to collect security events from Arc-enabled servers and send them to Log Analytics.
Azure Monitor Agent (AMA) is the recommended agent for log collection, replacing the legacy Log Analytics agent (MMA). DCRs define what data to collect and where to send it.
Overview
| Log Type | Source | Purpose |
|---|---|---|
| Windows Security Events | Windows Event Log | Authentication, authorization, policy changes |
| Syslog | Linux systems | System and security events |
| Performance Counters | OS metrics | Resource utilization and anomaly detection |
| Custom Logs | Application logs | Application-specific security events |
Prerequisites
- Log Analytics workspace created in Stage 06
- Azure Monitor Agent deployed (or will deploy via DCR)
- Arc-enabled servers registered (or will be during cluster deployment)
Variables from variables.yml
| Variable | Config Path | Example |
|---|---|---|
AZURE_SUBSCRIPTION_ID | azure.subscription.id | 00000000-0000-0000-0000-000000000000 |
AZURE_RESOURCE_GROUP | azure.resource_group.name | rg-azurelocal-prod-eus2 |
AZURE_REGION | azure.resource_group.location | eastus2 |
LOG_ANALYTICS_WORKSPACE_NAME | monitoring.log_analytics.workspace_name | law-azl-DAL-prod-01 |
Security Event Tiers
| Tier | Events Collected | Use Case |
|---|---|---|
| Minimal | Critical security events only | Cost-sensitive environments |
| Common | Important events (recommended) | Standard security monitoring |
| All | Complete security log | Compliance, forensics |
Procedure
- Azure Portal
- Direct Script (On Node)
- Standalone Script
Create Data Collection Rule for Security Events
- Navigate to Data Collection Rules
- In Azure Portal, search for Data collection rules
- Click + Create
- Configure Basics
- Rule Name:
dcr-security-events-prod-eus2 - Subscription: Select your subscription
- Resource Group:
rg-management-prod-eastus2 - Region: Same as Log Analytics workspace
- Platform Type: Windows (or All for both Windows and Linux)
- Add Resources (Optional)
- Click + Add resources
- Select Arc-enabled servers (if already registered)
- Or leave empty to assign later during cluster deployment
- Configure Data Sources
Windows Security Events:
- Click + Add data source
- Data source type: Windows Event Logs
- Configure: Select Security under Windows event logs
- Click Add data source
Windows Event Logs:
- Click + Add data source
- Data source type: Windows Event Logs
- Check: System, Application
- Configure XPath queries for specific events (optional)
- Configure Destination
- Click + Add destination
- Destination type: Azure Monitor Logs
- Subscription: Select your subscription
- Destination: Select your Log Analytics workspace
- Review and Create
- Click Review + create
- Click Create
Create Syslog Collection Rule (Linux)
- Create New DCR for Linux
- Rule Name:
dcr-syslog-security-prod-eus2 - Platform Type: Linux
- Add Syslog Data Source
- Click + Add data source
- Data source type: Linux Syslog
- Configure facilities:
auth- LOG_WARNING and aboveauthpriv- LOG_WARNING and abovesyslog- LOG_WARNING and abovedaemon- LOG_ERR and above
- Add Destination
- Select your Log Analytics workspace
- Click Create
# Variables
$subscriptionId = "<your-subscription-id>"
$resourceGroup = "rg-management-prod-eastus2"
$location = "eastus2"
$workspaceName = "law-azlmgmt-prod-eus2"
$dcrName = "dcr-security-events-prod-eus2"
# Set subscription context
az account set --subscription $subscriptionId
# Get Log Analytics workspace resource ID
$workspaceId = az monitor log-analytics workspace show `
--resource-group $resourceGroup `
--workspace-name $workspaceName `
--query id -o tsv
# Create Data Collection Rule for Windows Security Events
$dcrConfig = @"
{
"location": "$location",
"properties": {
"description": "Security event collection for Azure Local",
"dataSources": {
"windowsEventLogs": [
{
"name": "SecurityEvents",
"streams": ["Microsoft-SecurityEvent"],
"xPathQueries": [
"Security!*[System[(EventID=4624 or EventID=4625 or EventID=4648 or EventID=4672 or EventID=4688 or EventID=4697 or EventID=4698 or EventID=4719 or EventID=4720 or EventID=4722 or EventID=4723 or EventID=4724 or EventID=4725 or EventID=4726 or EventID=4728 or EventID=4732 or EventID=4735 or EventID=4738 or EventID=4740 or EventID=4756 or EventID=4767 or EventID=4768 or EventID=4769 or EventID=4771 or EventID=4776)]]"
]
},
{
"name": "SystemEvents",
"streams": ["Microsoft-Event"],
"xPathQueries": [
"System!*[System[(Level=1 or Level=2 or Level=3)]]",
"Application!*[System[(Level=1 or Level=2 or Level=3)]]"
]
}
]
},
"destinations": {
"logAnalytics": [
{
"workspaceResourceId": "$workspaceId",
"name": "securityWorkspace"
}
]
},
"dataFlows": [
{
"streams": ["Microsoft-SecurityEvent"],
"destinations": ["securityWorkspace"]
},
{
"streams": ["Microsoft-Event"],
"destinations": ["securityWorkspace"]
}
]
}
}
"@
# Save config to file
$dcrConfig | Out-File -FilePath "dcr-config.json" -Encoding UTF8
# Create DCR
az monitor data-collection rule create `
--name $dcrName `
--resource-group $resourceGroup `
--location $location `
--rule-file "dcr-config.json"
Write-Host "✅ Data Collection Rule created: $dcrName" -ForegroundColor Green
# Clean up temp file
Remove-Item "dcr-config.json"
# Variables
$subscriptionId = "<your-subscription-id>"
$resourceGroup = "rg-management-prod-eastus2"
$location = "eastus2"
$workspaceName = "law-azlmgmt-prod-eus2"
$dcrName = "dcr-security-events-prod-eus2"
# Connect and set context
Connect-AzAccount
Set-AzContext -SubscriptionId $subscriptionId
# Get Log Analytics workspace
$workspace = Get-AzOperationalInsightsWorkspace `
-ResourceGroupName $resourceGroup `
-Name $workspaceName
# Define Windows Security Event XPath queries (Common tier)
$securityXPathQueries = @(
# Logon events
"Security!*[System[(EventID=4624)]]", # Successful logon
"Security!*[System[(EventID=4625)]]", # Failed logon
"Security!*[System[(EventID=4648)]]", # Explicit credentials
"Security!*[System[(EventID=4672)]]", # Special privileges
# Account management
"Security!*[System[(EventID=4720)]]", # Account created
"Security!*[System[(EventID=4722)]]", # Account enabled
"Security!*[System[(EventID=4725)]]", # Account disabled
"Security!*[System[(EventID=4726)]]", # Account deleted
"Security!*[System[(EventID=4738)]]", # Account changed
# Group management
"Security!*[System[(EventID=4728)]]", # Member added to security group
"Security!*[System[(EventID=4732)]]", # Member added to local group
"Security!*[System[(EventID=4756)]]", # Member added to universal group
# Authentication
"Security!*[System[(EventID=4768)]]", # Kerberos TGT request
"Security!*[System[(EventID=4769)]]", # Kerberos service ticket
"Security!*[System[(EventID=4776)]]", # NTLM authentication
# Policy changes
"Security!*[System[(EventID=4719)]]" # Audit policy changed
)
# Create Data Collection Rule using ARM template
$dcrTemplate = @{
'$schema' = "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"
contentVersion = "1.0.0.0"
resources = @(
@{
type = "Microsoft.Insights/dataCollectionRules"
apiVersion = "2022-06-01"
name = $dcrName
location = $location
properties = @{
description = "Security event collection for Azure Local infrastructure"
dataSources = @{
windowsEventLogs = @(
@{
name = "SecurityEventDataSource"
streams = @("Microsoft-SecurityEvent")
xPathQueries = $securityXPathQueries
}
@{
name = "SystemEventDataSource"
streams = @("Microsoft-Event")
xPathQueries = @(
"System!*[System[(Level=1 or Level=2 or Level=3)]]"
"Application!*[System[(Level=1 or Level=2)]]"
)
}
)
}
destinations = @{
logAnalytics = @(
@{
workspaceResourceId = $workspace.ResourceId
name = "LogAnalyticsDestination"
}
)
}
dataFlows = @(
@{
streams = @("Microsoft-SecurityEvent")
destinations = @("LogAnalyticsDestination")
}
@{
streams = @("Microsoft-Event")
destinations = @("LogAnalyticsDestination")
}
)
}
}
)
}
# Convert to JSON and deploy
$templatePath = Join-Path $env:TEMP "dcr-template.json"
$dcrTemplate | ConvertTo-Json -Depth 20 | Out-File $templatePath -Encoding UTF8
New-AzResourceGroupDeployment `
-ResourceGroupName $resourceGroup `
-TemplateFile $templatePath `
-Name "DCR-SecurityEvents-Deployment"
Write-Host "✅ Data Collection Rule created: $dcrName" -ForegroundColor Green
# Clean up
Remove-Item $templatePath
Key Security Events to Collect
| Event ID | Description | Category |
|---|---|---|
| 4624 | Successful logon | Authentication |
| 4625 | Failed logon | Authentication |
| 4648 | Logon with explicit credentials | Authentication |
| 4672 | Special privileges assigned | Privilege Use |
| 4720 | User account created | Account Management |
| 4726 | User account deleted | Account Management |
| 4728 | Member added to security group | Group Management |
| 4738 | User account changed | Account Management |
| 4768 | Kerberos TGT requested | Kerberos |
| 4769 | Kerberos service ticket requested | Kerberos |
Validation
# Verify DCR exists
$dcr = Get-AzDataCollectionRule -ResourceGroupName $resourceGroup -Name $dcrName
if ($dcr) {
Write-Host "✅ DCR exists: $($dcr.Name)" -ForegroundColor Green
Write-Host " Location: $($dcr.Location)"
Write-Host " Data Sources: $($dcr.DataSource.WindowsEventLog.Count) Windows Event Logs"
} else {
Write-Host "❌ DCR not found" -ForegroundColor Red
}
# Query Log Analytics for security events (after data starts flowing)
$query = @"
SecurityEvent
| where TimeGenerated > ago(1h)
| summarize count() by EventID
| order by count_ desc
| take 10
"@
Write-Host "`nQuerying for security events..." -ForegroundColor Cyan
# Note: Events may take 5-10 minutes to appear after DCR association
Expected Output
After Arc-enabled servers are registered and associated with the DCR:
SecurityEvent
| summarize count() by EventID
EventID count_
------- ------
4624 1547
4625 23
4672 892
4648 156
4768 2341
4769 8923
Assigning DCR to Arc-Enabled Servers
Once Arc-enabled servers are registered during cluster deployment, associate them with the DCR:
# Get DCR resource ID
$dcrId = (Get-AzDataCollectionRule -ResourceGroupName $resourceGroup -Name $dcrName).Id
# Associate with Arc-enabled server
$arcServerResourceId = "/subscriptions/$subscriptionId/resourceGroups/rg-azurelocal-prod-eastus2/providers/Microsoft.HybridCompute/machines/azl-node-01"
New-AzDataCollectionRuleAssociation `
-TargetResourceId $arcServerResourceId `
-AssociationName "dcr-association-node01" `
-RuleId $dcrId
Troubleshooting
| Issue | Cause | Resolution |
|---|---|---|
DCR creation fails with WorkspaceId invalid | Log Analytics workspace not found or wrong region | Verify workspace exists with Get-AzOperationalInsightsWorkspace; ensure DCR and workspace are in the same region |
| Security events not appearing in Log Analytics | AMA not installed or DCR association missing | Verify AMA extension: az connectedmachine extension list; check DCR association: Get-AzDataCollectionRuleAssociation |
| Partial event collection (some event types missing) | DCR XPath queries don't cover required event channels | Update DCR data sources to include all required Windows event channels (Security, System, Application) |
Next Steps
Proceed to Task 6: PIM & Conditional Access to configure just-in-time access and identity protection.
Navigation
| Previous | Up | Next |
|---|---|---|
| ← Task 03: Security Baselines | Phase 04: Security & Governance | Task 05: Azure Update Manager → |
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0.0 | 2026-03-24 | Azure Local Cloudnology Team | Initial release |