AMA vs MMA Agent in Microsoft Sentinel: Complete 2026 Migration Guide
AMA vs MMA: Complete Migration Guide for Microsoft Sentinel
📋 Table of Contents
Microsoft retired the Log Analytics Agent (MMA / OMS Agent) on 31 August 2024. Organisations still running MMA are operating on an unsupported agent with no security patches and no new feature development. If you are running Microsoft Sentinel with any MMA-connected machines, migration to the Azure Monitor Agent (AMA) is not optional — it is overdue.
This guide gives you the full picture: what changed, why it matters for Sentinel specifically, and a concrete step-by-step migration path with verification queries.
1. Background: The Agent Transition
For years, Microsoft operated multiple overlapping agents: MMA (Microsoft Monitoring Agent, also called the Log Analytics Agent or OMS Agent), the Diagnostics Extension, and others. In 2021, Microsoft announced a unified replacement — the Azure Monitor Agent (AMA) — designed to consolidate all collection scenarios into a single, policy-driven agent with a modern architecture.
The key architectural shift: AMA does not rely on a workspace-level configuration. Instead, it is driven by Data Collection Rules (DCRs) — Azure Resource Manager resources that define what to collect, where to send it, and optionally how to transform it before ingestion.
2. What Was MMA?
The Microsoft Monitoring Agent was the workhorse of the original Azure Monitor and OMS ecosystem. It collected Windows Event logs, Syslog, performance counters, and IIS logs, sending them directly to one or more Log Analytics workspaces based on workspace-level settings.
- Configuration lived inside the Log Analytics workspace — every connected machine used the same settings
- Supported multi-homing: one agent could send to up to 4 workspaces simultaneously
- No built-in transformation — all data landed in the workspace as-is
- Managed via MMA settings UI or PowerShell — no Azure Policy integration
- End-of-support: 31 August 2024
3. What Is AMA?
The Azure Monitor Agent is the current-generation collection agent. It runs on Windows and Linux (including Azure VMs, Arc-enabled servers, and on-premises machines connected via Azure Arc).
- Configuration is fully externalised into DCRs — no per-machine agent configuration
- Supports multi-homing across workspaces via multiple DCRs
- Built-in KQL-based transformation at ingestion time via DCR transformations
- Deployable at scale via Azure Policy — push to all machines in a subscription or management group
- Supports data filtering before ingestion — reducing cost by dropping low-value rows
- Works with both Windows Event logs (XPath queries) and Linux Syslog (facility/severity filters)
4. Feature Comparison
| Feature | MMA (Legacy) | AMA (Current) |
|---|---|---|
| Configuration model | Workspace-level settings | DCR — Azure resource |
| Windows Event logs | Basic event ID list | XPath queries (flexible filtering) |
| Syslog | Facility/severity selection | Facility/severity via DCR |
| Multi-homing | Up to 4 workspaces | Multiple DCRs → multiple workspaces |
| Pre-ingestion transform | ❌ Not supported | ✅ KQL transformation in DCR |
| Azure Policy deployment | Limited | ✅ Full policy-based deployment |
| Azure Arc support | Partial | ✅ Full Arc support |
| Security patches | ❌ End of support Aug 2024 | ✅ Actively maintained |
5. Understanding Data Collection Rules
A DCR is an Azure Resource Manager object (type: Microsoft.Insights/dataCollectionRules) that defines the collection pipeline for one or more machines. Understanding DCR structure is essential before migrating.
DCR components
- Data Sources — what to collect: Windows Event logs (specified via XPath), Linux Syslog (facility + minimum severity), performance counters, text logs
- Streams — the intermediate data format:
Microsoft-Event,Microsoft-Syslog,Microsoft-CommonSecurityLog - Destinations — where to send: one or more Log Analytics workspaces
- Data Flows — maps streams to destinations, and optionally applies a KQL transformation
XPath filter example — Windows Security events
// XPath query for targeted Security event collection in DCR // Collects only logon (4624, 4625), privilege use (4672), and process creation (4688) Security!*[System[(EventID=4624 or EventID=4625 or EventID=4672 or EventID=4688)]] // For all Security events (high volume — not recommended without DCR filter): Security!*
6. Step-by-Step Migration
-
Inventory MMA-connected machines
Run the KQL below to find all machines currently reporting via MMA vs AMA. - Create DCRs that replicate your existing workspace collection settings. For Sentinel, use the built-in Sentinel data connectors that now deploy AMA + DCR automatically.
- Deploy AMA to machines via Azure Policy (built-in policies exist for Windows and Linux, both Azure VMs and Arc-enabled servers).
- Validate data flow — run the post-migration verification queries below and confirm equivalent event coverage.
- Run both agents in parallel for 7–14 days to confirm parity. Watch for duplicate data (both agents sending the same events simultaneously — this doubles ingestion cost temporarily).
- Uninstall MMA once parity is confirmed. Use Azure Policy “Deny” to prevent re-installation.
// Find machines reporting via MMA (legacy) Heartbeat | where TimeGenerated > ago(1d) | where Category == "Direct Agent" // MMA reports as "Direct Agent" | summarize LastSeen = max(TimeGenerated) by Computer, Category | order by LastSeen desc // Find machines reporting via AMA Heartbeat | where TimeGenerated > ago(1d) | where Category == "Azure Monitor Agent" | summarize LastSeen = max(TimeGenerated) by Computer, Category | order by LastSeen desc // Detect dual-reporting machines (MMA + AMA both active — watch for cost doubling) Heartbeat | where TimeGenerated > ago(1d) | summarize Categories = make_set(Category) by Computer | where array_length(Categories) > 1 | project Computer, Categories
7. Post-Migration Verification
// Verify Security event collection post-migration
SecurityEvent
| where TimeGenerated > ago(24h)
| summarize EventCount = count() by Computer, bin(TimeGenerated, 1h)
| order by TimeGenerated desc, EventCount desc
// Compare event volume before and after (adjust dates to your cutover date)
SecurityEvent
| where TimeGenerated between (ago(14d) .. ago(7d)) // Pre-migration week
| summarize PreMigrationCount = count()
| extend Period = "Pre-Migration"
| union (
SecurityEvent
| where TimeGenerated > ago(7d) // Post-migration week
| summarize PreMigrationCount = count()
| extend Period = "Post-Migration"
)
| project Period, EventCount = PreMigrationCount
