By the end of this you know exactly which disruption actions your tenant can execute rather than which ones it is licensed for, every per-workload prerequisite has been proven rather than assumed, your exclusions are a register with owners and reasons instead of a page somebody edited once, and you have run the only end-to-end test that current documentation actually supports. You will also know the four places where Microsoft gives you no way to read back what you configured, because those are the gaps your operating procedure has to cover by hand.
Prerequisites
You need Security Administrator in Microsoft Entra ID, or the equivalent unified role built in the activation build sheet, plus the Core security settings management permission if your tenant runs the unified model. You need Exchange Online PowerShell with a role that can read organisation and mailbox configuration, and Domain Admin or equivalent for the domain controller auditing work. One qualifying licence lights the engine, and the list is broad, so assume you qualify and spend your effort on coverage instead. On the workstation you run this from you need three PowerShell modules, none of which ships by default: the Active Directory module from the remote administration tools, the DefenderForIdentity module, and ExchangeOnlineManagement. Pin and record the versions you tested. For the end-to-end test you additionally need the Active remediation actions role under Defender for Endpoint role-based access control, a disposable onboarded device, a disposable unmanaged device or one you are willing to have discovered, and a disposable test account that nothing depends on. Do not use a real administrator account as the test subject, for reasons that will be obvious by the end.
Set expectations on scope before you start. Six workloads contribute prerequisites and there is no single page, report or interface that will tell you whether disruption is ready. That absence is the reason this article exists.
Step 1: Build the coverage grid before touching anything
Write down, per action, whether your tenant can execute it today. The question is what you deployed, not what you are entitled to. Microsoft states the principle plainly, that each product must be deployed to execute its own response actions, and this grid is that principle applied to your estate.
| Setting | Value | Why |
|---|---|---|
| Contain device, Contain IP | Requires Defender for Endpoint onboarded broadly | Enforcement is performed by the onboarded fleet, not by the compromised asset. Coverage is a function of how many devices you onboarded, so a partial rollout is a partially effective control. |
| Isolate device (automatic) | Requires Defender for Endpoint, preview, end-user workstations only | Does not apply to servers. Still in preview, so do not build a control objective whose only evidence is this action. |
| Contain user | Requires Defender for Endpoint on the enforcing devices | Enforced at the endpoint rather than in the directory, so the identity keeps working anywhere your endpoint agent is not. |
| Disable user, on-premises account | Requires a Defender for Identity sensor on the domain controller that will perform it | Sensors on federation, certificate and directory synchronisation servers contribute signal and take no remediation action. |
| Disable user, cloud-only account | Requires nothing beyond Microsoft Entra ID | Executed through a Microsoft-managed enterprise application and explicitly not dependent on deploying the identity product. This is the one row most estates get for free. |
| Revoke user session | Requires Microsoft Entra ID | The cheapest containment in the catalogue and the one most likely to already work. |
| Suspend user in Entra | Requires Microsoft Entra ID | A separate action from session revocation, suspending the account in the directory rather than terminating tokens. Generally available, and like the cloud-only disable it needs nothing beyond Entra ID. |
| Mail signal (no action of its own) | Requires Exchange Online mailbox auditing | Mail contributes no response action, but the five audited mailbox events are what several detections are built from, which is why step 7 audits a workload that has no row of its own in the action catalogue. |
| Compromised OAuth application | Requires Defender for Cloud Apps with the Microsoft 365 connector fully configured | A partially configured connector produces partial functionality rather than an error, which is step 6. |
| Okta suspension, AWS deny policy | Requires a Microsoft Sentinel workspace and the relevant connector, both preview | The only disruption actions that need a workspace, which is a real input to the decision argued later in this block. |
Six workloads contribute to this and only five of them can act, which is why the mail row above carries no action. The output of this step is one page naming which rows you can execute, which you cannot, and which you have decided not to pursue. Keep it, because it is the document that answers the question a board asks after an incident, which is whether the platform could have acted and chose not to, or could not act at all.
Step 2: Endpoint, set device discovery to standard and understand how it is scoped
Standard discovery is a documented hard prerequisite for automatic device containment, because containing an asset that was never onboarded requires having discovered it. In the Defender portal open Settings, then Device discovery, and confirm Discovery mode is set to Standard discovery (recommended) rather than Basic. Standard has been the default since July 2021, so most tenants are already correct here and the point of the step is to prove it rather than to change it.
The trap is in how you scope it, and it catches people who have done this before in another product. Scoping is by device tag, not by device group. You choose either all devices (recommended) or Select tags, and if you choose tags then every device that does not carry one of those tags runs basic discovery only. So a tenant that narrowed standard discovery to a tagged subset years ago, for perfectly good network reasons, has silently narrowed the population that automatic containment can act on, and nothing anywhere reports that as a gap.
| Setting | Value | Why |
|---|---|---|
| Discovery mode | Standard discovery (recommended) | Documented prerequisite for the automatic Contain Device action. Basic is passive collection only. |
| Devices performing discovery | all devices (recommended) | Any tag-based narrowing drops every untagged device to basic. Choose tags only where a network genuinely cannot tolerate active probing, and record which segments you excluded. |
| Exclusions | IP addresses or subnets only | Exclusions do not accept device groups, despite one Microsoft page saying they do. Use them for fragile network segments, not as a device-population control. |
| Naming, for any discovery tag | Disc-Standard-<Segment> | Makes the purpose of the tag readable in the device inventory, where tags from four different projects otherwise accumulate with no owner. |
State the gap honestly in your own documentation: Microsoft publishes no interface for reading or setting the discovery mode. This is a portal setting with a portal readback, so the control evidence for an audit is a person looking at the page on a date, and your process needs to say who and how often.
Step 3: Endpoint, audit every device group’s remediation level
Open Settings, then Endpoints, then Device groups, and read the Remediation level column for every group. One value excludes a group from automated containment entirely, and it is the single most consequential setting in this article: No automated response. A group set to that value is not covered by disruption, whatever the rest of your configuration says.
Before you read the column, know that Microsoft is currently using two vocabularies for the same five values, and the page that documents the creation wizard uses the shorter one. Map them once, in your own runbook, or two engineers reading two Microsoft pages will conclude these are different settings.
| Setting | Value | Why |
|---|---|---|
| As shown in the device group wizard | Full remediation | Equivalent to the longer form Full - remediate threats automatically used on the disruption prerequisite page. This is the target state for every group you can defend. |
| As shown in the device group wizard | Semi - Approval required for all folders | Longer form: Semi - require approval for all folders. Semi levels still permit disruption to act; only the fifth value excludes a group. |
| As shown in the device group wizard | Semi - Approval required for system folders | Longer form: Semi - require approval for core folders remediation. The two names describe one setting and the mapping is not published anywhere. |
| As shown in the device group wizard | Semi - Approval required for non-temporary folders | Longer form: Semi - require approval for non-temp folders remediation. |
| As shown in the device group wizard | No automated response | The exclusion. Identical in both vocabularies, which is fortunate, because this is the one you must be able to find reliably. |
Ungrouped devices (default) | Set deliberately, usually Full remediation | This group cannot be deleted or reranked but its remediation level is editable, and it is where every newly onboarded device lands before your rules match it. Left wrong, it is a rolling gap that refills itself. |
A tenant supports up to two thousand device groups, and changes to group configuration take minutes and in some environments hours to propagate, so do not verify a change you made ninety seconds ago and conclude it failed. More importantly, there is no supported interface that reads remediation levels across groups. The device object exposes only which group it belongs to, never that group’s level, so an estate with sixty device groups audits this by opening a page and reading sixty rows. If you want it evidenced over time, the honest mechanism is a dated note by a named person recording what each group’s level was, not a report.
One dated caveat belongs in your notes rather than in your design. This same remediation level is the automated investigation setting, and investigations stop running for endpoint on 1 September 2026 while the disruption prerequisite page still instructs you to configure the level. Microsoft has not reconciled the two. Configure it as documented, and expect this control to be restated.
Step 4: Identity, prove domain controller auditing rather than assuming it
The identity sensor cannot raise what it cannot see, and the audit configuration is the most commonly half-finished prerequisite in this whole list. There are two supported ways to configure it and you should pick one deliberately rather than ending up with both. The first is Automatic Windows auditing configuration, an advanced feature under Settings and Identities, which applies the audit policy, the NTLM auditing, the domain object auditing and the federation container auditing for you and re-applies them once every twenty four hours. It works only for current-generation sensors on domain controllers, and Microsoft warns that Group Policy settings can conflict with what the sensor sets locally.
The second is Group Policy plus the DefenderForIdentity PowerShell module, which is the right choice for an estate that manages domain controller policy as code and does not want an agent editing local policy. Install the module and pin the version you tested, recording it in your runbook; Microsoft publishes the module’s version only on the gallery and not in its documentation, so there is no version number to quote here and any that appeared would be invented.
# Read the current state before changing anything. Run from a domain-joined
# admin workstation with the DefenderForIdentity module installed.
$ErrorActionPreference = 'Stop'
# Assert you are in the domain you think you are in.
$domain = (Get-ADDomain).DNSRoot
if ($domain -ne '') { throw "Wrong domain: $domain" }
# Domain mode looks for the MDI configuration GPOs BY NAME PREFIX.
# Supply the prefix your Set-MDIConfiguration run used, or every area
# returns false because the GPO was not found rather than because
# auditing is off.
$prefix = ''
'AdvancedAuditPolicyDCs','DomainObjectAuditing','NTLMAuditing',
'ConfigurationContainerAuditing','AdfsAuditing' | ForEach-Object {
$result = Test-MDIConfiguration -Mode Domain -Configuration $_ -GpoNamePrefix $prefix
if ($result -isnot [bool]) {
throw "Unexpected return type from Test-MDIConfiguration: $($result.GetType().FullName)"
}
[pscustomobject]@{ Area = $_; Pass = ($result -eq $true) }
} | Format-Table -AutoSize
# Full evidence pack, including the SACLs, as an HTML report you can keep.
# -Identity takes your EXISTING Defender for Identity service account in
# DOMAIN\samAccountName form. It is required in Domain mode only to avoid
# an interactive credential prompt, and it is documented in the parameter
# table while being absent from the published syntax block.
New-MDIConfigurationReport -Path 'C:\MDI' -Mode Domain `
-Identity '\' -OpenHtmlReport
Expected result: a boolean per area, and an HTML report enumerating what is set against what is required. The failure mode here is the most important in this article, because it produces a confident wrong answer in the direction of alarm. Domain mode does not inspect the domain controllers. It looks for the configuration Group Policy objects by name prefix, which is why the cmdlet takes a prefix parameter at all. So a false does not mean auditing is off, it means the expected policy object was not found under that name.
That matters most on the path Microsoft recommends. Automatic Windows auditing configuration applies its settings to the domain controller’s local system policy and creates no Group Policy objects at all, so an estate that took the recommended route and is correctly configured will fail all five areas of this check. If that is your path, this cmdlet is not your readback: use the health issues below, and read Get-MDIConfiguration for its detail column rather than its boolean. If you configured by policy, pass the prefix your own run used. Do not respond to a false here by building Advanced Audit Policy objects on domain controllers that a sensor is already configuring locally, because Microsoft warns explicitly that policy settings and sensor-applied local settings conflict.
Two smaller failure modes. Omitting the identity parameter on a domain-mode report drops you into an interactive credential prompt, which is fine at a desk and fatal in a scheduled job. And the cmdlet is documented in the module reference but is no longer referenced from the deployment article at all, so an engineer following the deployment page will never meet it; that is a documentation gap rather than a deprecation, and the cmdlet works.
Three details in the audit requirements are worth calling out because each has bitten a real deployment. The security group management subcategory covers events 4728, 4729, 4730, 4732, 4733, 4756, 4757 and 4758, and 4731 is not among them, so a policy written from a range rather than from the enumeration claims coverage it does not have. The domain root system access control list must be applied to every listed object class and not only to user objects, and the delegated managed service account class in that list is meaningful only where at least one Windows Server 2025 domain controller exists. And Microsoft now calls these Audit (Premium) Policy settings on the configuration page, meaning Advanced Audit Policy Configuration in Group Policy, which has nothing whatsoever to do with the Purview audit tier discussed in step 7. Conflating those two costs an afternoon.
Two pieces of cleanup are now owed on any estate configured before this year. Diagnostic logging of 1644 events is no longer required, so the field engineering diagnostics value and the directory search threshold values should come back out. And from sensor version 3.0.8 remote procedure call auditing is enabled automatically on upgrade, so the tag that used to be required for it is not.
Finish the step at Settings, Identities, Deployment, Health issues, and confirm nothing open relates to auditing. The six names to look for are the NTLM auditing issue, the directory services advanced auditing issue, the directory services object auditing issue, and the configuration container, federation container and certificate services auditing issues. They validate once a day, three per sensor and three per domain, so a fix made this morning is not disproved by a health issue still showing this afternoon. There is one known issue that undercuts this as a gate: on current sensors configured manually through Group Policy or PowerShell, these health alerts can persist even when auditing is correct. If you configured by policy and the alert will not clear, verify with the module rather than trusting the portal.
Step 5: Identity, settle the action account question
Open Settings, Identities, Manage action accounts. If every sensor in the estate is current generation, select Automatically use the sensor’s local system account and stop, because that is what the sensor will do regardless. This is a real change and it invalidates earlier designs: current sensors always act as the domain controller’s local system account and do not use a group managed service account configured for the previous generation, whatever the portal shows. An estate mid-migration should keep the service account configured for as long as older sensors remain and should expect the credential health alert until the last one is upgraded.
There is no test control for an action account. No button, no cmdlet, nothing. The module’s account test validates the directory service account, which is the account used to read directory data and is a different thing entirely; Microsoft says so explicitly on the page, and people conflate them anyway. The only validation of the action path is performing a disable, which is why the end-to-end test at the bottom of this sheet does exactly that.
Finally, confirm the sensor is on the right machine. The disable is performed by the sensor on the domain controller that will do it, so a design with sensors on two of five controllers has a disable path that depends on which controller the platform reaches. And check your joiner-mover-leaver automation while you are here, because Microsoft warns about exactly this: a scheduled process that enforces that all active employees have enabled accounts will helpfully re-enable an account that disruption disabled during an attack. That is not a theoretical conflict. Go and read what your identity lifecycle tooling does on a schedule.
Step 6: Cloud apps, and the connector that changed under you
The action against a compromised application registration depends on the Microsoft 365 connector being completely configured. Microsoft’s requirement is that every component is selected, including the option enabling Microsoft Entra ID applications, and that a partial configuration produces degraded functionality and operation failures rather than an error you would notice. Open Settings, Cloud apps, Connected apps, App connectors, and confirm the Microsoft 365 connector reads Connected. Then open its component selection and confirm every component is selected.
This is the step most likely to find something, because the defaults changed. Microsoft added default components in January 2026 and states that an application configured before then must have all default options selected and be connected again to pick them up. A connector configured in 2024 therefore looks connected, reports no error, and is missing components that current disruption behaviour depends on. Re-run the connection on any connector older than this year, as a matter of course rather than on suspicion.
The sheet stops short in two places and both are Microsoft’s limits rather than mine. Microsoft does not enumerate the individual component names anywhere in text; Microsoft does not publish them in text anywhere, so this sheet will not print a list it cannot source, and the durable instruction is to select every component offered on the selection page including the Entra ID applications option. And file protection additionally requires file monitoring, which is a separate setting under Settings, Cloud Apps, Files, Enable file monitoring, without which the product does not scan or store organisational files at all.
Step 7: Mail, prove the audit surface survived your predecessors
Disruption depends on five mailbox audit actions being logged: MailItemsAccessed, UpdateInboxRules, MoveToDeletedItems, SoftDelete and HardDelete. All five are in the default audit sets for administrator, delegate and owner sign-in types, which means a tenant nobody has customised is already correct and this step is a proof rather than a change. The work is finding the mailboxes where somebody customised the audit set years ago, because a customised mailbox stops receiving new default actions and there is no alert when that happens.
# Exchange Online. Pin the module version you tested and record it.
$ErrorActionPreference = 'Stop'
Connect-ExchangeOnline
# Assert the tenant before reading anything.
$org = (Get-OrganizationConfig).Identity
if ($org -notlike '*') { throw "Wrong tenant: $org" }
# Gate 1: organisation level. False means auditing is ON. Double negative, read twice.
Get-OrganizationConfig | Format-List AuditDisabled
# Gate 2: per mailbox. Join before comparing. DefaultAuditSet is a
# multi-valued property, not a string, and comparing it to a rendered
# string returns the non-matching elements rather than a boolean.
Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox,SharedMailbox |
Where-Object { (($_.DefaultAuditSet | Sort-Object) -join ',') -ne 'Admin,Delegate,Owner' } |
Select-Object UserPrincipalName, RecipientTypeDetails,
@{ n='DefaultAuditSet'; e={ $_.DefaultAuditSet -join ',' } }
# Gate 3: bypass. True here makes the mailbox invisible to disruption.
Get-MailboxAuditBypassAssociation -ResultSize Unlimited |
Where-Object { $_.AuditByPassEnabled } |
Select-Object Name, AuditByPassEnabled
Expected result: gate one returns False, gate two returns nothing, gate three returns nothing. The join in gate two is the whole point of it and the reason a naive version of this check is worse than none. DefaultAuditSet is a multi-valued property that merely renders as a comma-separated string, so comparing it directly against that rendered form returns the elements that did not match rather than a true or false. A compliant mailbox then reports as customised, and a mailbox whose value is blank, which is the one case that genuinely fails the prerequisite, reports as clean. Join first and you get the answer you asked for.
Two further failure modes. A blank value means every sign-in type was customised rather than that the mailbox is unconfigured, which is why it must not be allowed to pass silently. And bypass associations are ignored while organisation-level auditing is disabled, so a tenant that fails gate one will show a misleadingly clean gate three. On casing, Microsoft’s two pages disagree about AuditByPassEnabled; PowerShell is case-insensitive so both forms work, and it matters only if you are string-matching property names in a report.
Remediate a customised mailbox by restoring the default set rather than by adding the missing actions one at a time. The reason is durability: a mailbox on the default set automatically picks up any new audit action Microsoft ships, and a mailbox with a hand-built list never does, so piecemeal remediation recreates the same problem for whoever inherits it.
Set-Mailbox -Identity '' -DefaultAuditSet Admin,Delegate,Owner
# Read it back as a joined string, not as a rendered property.
(Get-Mailbox -Identity '').DefaultAuditSet -join ','
Three populations cannot reach the full five actions and you should record them as accepted gaps rather than chase them. Microsoft 365 group mailboxes do not carry mail item access or inbox rule auditing at all and their audit set cannot be customised. Public folder and resource mailboxes have no auditing support. And in a multigeo tenant, cross-geo mailbox auditing is not supported, so access to a shared mailbox from another geography does not land in that mailbox’s audit log.
One widely repeated claim to stop repeating: mail item access auditing is not restricted to the top licence tiers. Microsoft documents it as part of the standard audit capability, enabled by default for users holding an E3 or E5 licence in either the Office or Microsoft 365 family. There is a premium property carried on those records and there is a different, older audit action that genuinely is restricted to accounts without the higher licences, which is almost certainly where the confusion started. If somebody tells you your third-tier mailboxes cannot satisfy this prerequisite, that is not what the mailbox auditing documentation says, although one shared-mailbox investigation page still asserts an E5 requirement and has never been reconciled. Cite the audit standard page.
Step 8: Build the exclusion register, then configure from it
Write the register first, in whatever system already holds your control exceptions, and configure the portal from it rather than the other way round. Each row names the excluded object, the reason, an owner, a review date and a change reference. This is not process theatre. There is no export and no programmatic surface for these exclusions, and the only in-band record is a free text note field, so the register is the only durable evidence that anybody decided this.
Exclusions are reached at Settings, Microsoft Defender XDR, Automated response, which gives an Identities page and a Devices page, the latter carrying tabs for device groups, policy application and addresses. Keep the list short, because Microsoft documents exclusions as not recommended and every row is a place the platform has been told to stand down.
| Setting | Value | Why |
|---|---|---|
| Identity exclusions | Break-glass accounts only | The one category with an unarguable case: an account whose whole purpose is to work when everything else has failed must not be disabled by an automated system during the event it exists for. |
| Address exclusions, name | ADX-<Purpose>-<Ticket> | The name is one of only two free text fields you get. Carrying the change reference in it means the portal row points at the decision even when the register is not to hand. |
| Address exclusions, note | Owner, reason and review date | The only in-band justification record that exists anywhere for these objects. An empty note is an exclusion nobody can defend in twelve months. |
| Device group level | Avoid No automated response | The blunt lever. It removes the group from disruption entirely, and Microsoft cautions that excluding device groups from automated responses also affects automated investigation and response. Since the newer per-control preview arrived it is rarely the proportionate answer. |
| Policy application rule, tag | ADX-Policy-<AssetClass> | Dynamic tags are created under asset rule management, then a rule targets the tag. Naming the asset class rather than the incident keeps the tag meaningful after the person who created it has left. |
| Review cadence | Quarterly, named owner | Nothing expires these. An exclusion added for a two week migration in 2024 is still excluded, and no interface will tell you. |
Worked example, and it is the one that shows why the newer control earns its place. A manufacturing site runs eleven Windows machines that drive line equipment. They are onboarded, they matter, and the site engineering team will not accept an automated system severing their network. The old answer was to put them in a device group set to No automated response, which removes them from disruption completely and leaves the loudest possible gap in the estate. The current answer is to create a dynamic tag named ADX-Policy-LineControllers under asset rule management, matched on the naming or operating system properties those machines already carry, then create a policy application rule against that tag which disables only the specific control the engineering team objects to, and leave the device group at Full remediation. The machines stay covered by everything else. The exception is one control wide rather than one product wide, and the register row says which control, who asked, and when it gets reviewed.
Write the following into the register rather than discovering it later. The list of controls you can exclude in that rule is not published in text anywhere, so record what you selected at the time you select it; nothing will tell you later. And this feature is in preview, so pair it with a note about what you would fall back to.
While you are documenting exceptions, account for the other place they can live. High-impact response actions, live response included, can be restricted separately on assets designated as high value, which became generally available in June 2026. The response article argues which of the two should be your record of intent; the mechanical requirement here is that whichever you choose, the other one gets a row in the same register rather than a life of its own.
The roles for all of this depend on whether the unified model is active in your tenant. With it inactive, this needs Security Administrator or Global Administrator. With it active, a Security Operator or higher directory role, or the core security settings management permission, is enough, and a Security Reader can read the exclusions and tags without editing them. That read-only grant is what you give an auditor.
Step 9: Route the notification for disrupted incidents
An automated system that acts without approval must tell somebody it acted. If you built incident notification rules in the previous build sheet, this is a review rather than new work: confirm at least one rule covers high severity across the device groups that matter, that a test message has been delivered to a monitored destination, and that the tenant-specific portal link option is on so a responder lands in the right tenant at three in the morning.
Be clear about what that rule can and cannot filter. The wizard filters on severity and device group scope, not on whether an incident was disrupted, so there is no rule that means notify me when the platform acted on its own. The disruption tag, the banner, the summary card and the activities view are all portal surfaces you go and look at. Design the human process accordingly: the mail tells somebody an incident of consequence exists, and the portal tells them whether something has already been done about it.
Step 10: The consolidated readback
Three of the nine steps above have a programmatic readback and six do not, so this is a partial script by necessity rather than by omission. Microsoft publishes no interface for the discovery mode, none for device group remediation levels, none for the exclusion list, and no test for an action account. Run what can be run, and let the script print the gaps as gaps so that a reader of its output is not misled into thinking a clean run means a ready tenant.
# Attack disruption readiness: the machine-checkable subset.
# Everything printed as MANUAL has no documented programmatic surface.
$ErrorActionPreference = 'Stop'
$results = [System.Collections.Generic.List[object]]::new()
function Add-Result($area, $check, $state) {
$results.Add([pscustomobject]@{ Area = $area; Check = $check; State = $state })
}
# --- Identity: domain controller auditing ---
# GPO-configured estates only. On the automatic auditing path this whole
# block is not applicable; it reports the absence of GPOs, not the state
# of auditing. Set $prefix to $null to skip it honestly.
$prefix = ''
if ($prefix) {
foreach ($area in 'AdvancedAuditPolicyDCs','DomainObjectAuditing','NTLMAuditing') {
try {
$r = Test-MDIConfiguration -Mode Domain -Configuration $area -GpoNamePrefix $prefix
if ($r -isnot [bool]) { throw "Unexpected return type: $($r.GetType().FullName)" }
Add-Result 'Identity' $area $(if ($r -eq $true) { 'PASS' } else { 'FAIL' })
} catch { Add-Result 'Identity' $area "ERROR: $($_.Exception.Message)" }
}
} else {
Add-Result 'Identity' 'DC auditing (automatic configuration path)' 'MANUAL'
}
# --- Mail: audit surface ---
try {
Connect-ExchangeOnline
$auditDisabled = (Get-OrganizationConfig).AuditDisabled
Add-Result 'Mail' 'Organisation auditing enabled' $(if (-not $auditDisabled) { 'PASS' } else { 'FAIL' })
# Join before comparing. See step 7.
$customised = @(Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox,SharedMailbox |
Where-Object { (($_.DefaultAuditSet | Sort-Object) -join ',') -ne 'Admin,Delegate,Owner' })
Add-Result 'Mail' "Mailboxes off the default audit set: $($customised.Count)" `
$(if ($customised.Count -eq 0) { 'PASS' } else { 'FAIL' })
$bypassed = @(Get-MailboxAuditBypassAssociation -ResultSize Unlimited |
Where-Object { $_.AuditByPassEnabled })
Add-Result 'Mail' "Mailboxes bypassing audit: $($bypassed.Count)" `
$(if ($bypassed.Count -eq 0) { 'PASS' } else { 'FAIL' })
} catch { Add-Result 'Mail' 'Exchange Online checks' "ERROR: $($_.Exception.Message)" }
# --- Endpoint: contain-user enforcement floor, per device, run locally ---
# Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Advanced Threat Protection\Status' -Name "MsSenseDllVersion"
# --- The gaps, printed so nobody mistakes silence for success ---
Add-Result 'Endpoint' 'Device discovery mode is Standard' 'MANUAL'
Add-Result 'Endpoint' 'Device group remediation levels' 'MANUAL'
Add-Result 'Cloud apps' 'Microsoft 365 connector completeness' 'MANUAL'
Add-Result 'Identity' 'Action account posture' 'MANUAL'
Add-Result 'Platform' 'Exclusion register matches the portal' 'MANUAL'
$results | Sort-Object Area, Check | Format-Table -AutoSize
Expected result: a table with no FAIL rows and five MANUAL rows. The failure mode to guard against is cultural rather than technical, which is that a green script becomes the evidence and the five manual checks quietly stop being done. Put the manual rows in the same output for exactly that reason.
The endpoint version floor is a per-device check rather than a tenant one, which is why it sits commented out above. The contain user action requires a minimum sensor client version on the devices doing the enforcing. The disruption prerequisites page gives 10.8470; the device response actions page gives 8740 for the same capability, which read as a build is 10.8740. The two differ by what looks like a transposition and Microsoft has not reconciled them. Gate on 10.8740 if you want the conservative reading, and record which figure you used.
Validation
Start by being precise about what cannot be validated. There is no documented, safe way to trigger the automatic disruption flow. The evaluation lab that used to provide one no longer exists, and it went without a retirement notice: its documentation now redirects to an unrelated antivirus evaluation page, while Microsoft’s own pilot guidance still links to it. The demonstration scenarios that replaced the older simulation article validate attack surface reduction, next generation protection and endpoint detection, and contain no reference to disruption at all. No simulator, test mode or customer-facing audit mode has shipped. If you read that Microsoft validates detectors in audit mode before release, that describes their release engineering and not a control available to you.
So validation here is prerequisite proof plus manual exercise of the same action paths the automatic flow would use. That is a weaker claim than a triggered end-to-end test and you should describe it that way in your own documentation rather than overstating it.
The hunting evidence has its own caveats and they matter enough to state before the query. The disruption events table’s status is contested: Microsoft declared it generally available in the June 2026 release notes while the schema reference still marks it preview, so treat it as preview for control-evidence purposes until the reference catches up. It records the outcomes of containment rather than the act of containing, so a contained user shows up as blocked logons and blocked file access rather than as a containment event. It exposes endpoint-based controls only. And the sample queries elsewhere in Microsoft’s own documentation project four columns that the table reference does not list, a disagreement Microsoft has not resolved. Query the documented columns.
// Disruption outcomes over the retained window, documented columns only.
DisruptionAndResponseEvents
| where Timestamp > ago(30d)
| project Timestamp, ActionType, DeviceName, SourceUserName,
Service, PolicyName, IsPolicyOn, ReportType
| order by Timestamp desc
Expected result on a healthy tenant that has not been attacked: nothing. An empty result is the normal state and is not evidence of a misconfiguration, which is precisely why the prerequisite proof above carries the weight. When rows do appear, the action types are user containment outcomes such as a blocked logon, a blocked file open or a disconnected remote desktop session, plus the predictive shielding actions, which share this table and the same portal filter. An auditor filtering for disruption activity is also seeing pre-emptive shielding activity, and the two are different decisions.
Two containment queries exist alongside that one and they answer a different question. DeviceEvents | where ActionType contains "ContainedDevice" returns activity that was blocked because a device was contained, and the same query with ContainedUser does it for a contained user. Both are documented. Neither logs the containment itself, which is the distinction worth holding: the act of containing is Action center evidence, and the blocks resulting from containment are hunting evidence. Use the device-derived query in the end-to-end test below, because it is the only thing that proves enforcement reached the fleet rather than proving a button worked.
// Discovery coverage: assets the platform can see and could contain,
// but which are not onboarded. This is the population Contain IP exists for.
DeviceInfo
| summarize arg_max(Timestamp, *) by DeviceId
| where OnboardingStatus == "Can be onboarded"
| count
Expected result: a number greater than zero on any real estate. Do not read this as a test of the discovery mode, because it is not one. Basic discovery is passive collection and still populates the inventory, so a tenant narrowed to a tag set or dropped to Basic will still return a healthy count here. What the number actually tells you is the size of the population that Contain IP exists for, which is worth knowing on its own. The readback for the mode itself is the portal page, as step 2 concedes. While you are there, confirm device discovery has not been switched off wholesale on the advanced features page, which makes the Standard and Basic distinction moot.
The end-to-end test
One test, run against disposable assets, exercising both response paths and both reversals. Announce it first, because containment is visible across the whole onboarded fleet and somebody will open a ticket.
Three safety checks before you start, because containment has documented collateral. Confirm the target holds a dedicated address that is not shared and was not recently recycled by your address assignment, since devices sharing an address with a contained one are affected too. Confirm it is not a network device and not acting as a default gateway, which Microsoft calls out specifically as a connectivity risk. And expect up to five minutes for containment to propagate to the fleet and the same again on release, so do not conclude from an immediate retest that nothing happened.
Record one thing before you act: which device group your test device resolves to, and that group’s remediation level. If it is No automated response, the test below will pass while disruption is switched off for that group, which is exactly the false pass this sheet exists to prevent.
Now the device path, and note that the two actions apply to different populations. Contain device is the control for an unmanaged or discovered asset, so run it against your disposable unmanaged device and reverse it with Release from containment. Isolate device is the control for an onboarded one, so run that against your onboarded test device and reverse it with Release from isolation, remembering that isolation also lifts itself after seven days. In both cases confirm from a second onboarded machine that traffic to the target is refused, which is the assertion that proves the enforcement fabric rather than the button, and confirm each action appears in the Action center history with an actor and a timestamp.
Then prove enforcement in the data rather than in the interface. Within a few minutes of the containment, the blocked traffic should be queryable.
// Blocks that happened because a device was contained.
DeviceEvents
| where Timestamp > ago(1h)
| where ActionType contains "ContainedDevice"
| project Timestamp, DeviceName, ActionType, RemoteIP
| order by Timestamp desc
Expected result: at least one row, raised by an onboarded device other than the one you contained. That is the proof, because it shows a third machine enforcing your decision. An empty result with a containment visible in the Action center means the containment has not reached the fleet yet, or nothing has tried to talk to the target; generate traffic from the second machine and re-run.
Now the identity path. Disable your disposable on-premises test account from the portal and confirm the account is disabled in Active Directory rather than only in the cloud, which is the assertion that proves the sensor is where you think it is. If your test account is cloud-only, you have proved a different path, and you should run both if your estate contains both. Re-enable it afterwards, and confirm your identity lifecycle automation did not do that for you before you got there, which is a finding in its own right if it did.
Expected result: containment enforced by other devices rather than by the contained one and visible in the device events data, the domain controller performing the disable, both actions attributable in the Action center, and both reversed. If containment does not take effect, the enforcing devices are the suspect rather than the target. If the disable lands only in the cloud, the sensor is not on the controller that ran it.
Be exact about what this proves, because the temptation is to over-claim it in a control document. It proves the action paths work and that enforcement reaches the fleet. It does not prove the automatic trigger, because no documented way to exercise that exists, and it does not by itself prove any of the prerequisites in steps 2 through 7: a manual containment succeeds on a tenant with a device group set to no automated response, with discovery on basic, with an incomplete cloud apps connector and with mailboxes bypassing audit. The prerequisite proof and the action test are two separate pieces of evidence and your documentation should present them as two.
Test the reversal path for user containment as a paper exercise rather than a live one, because that action cannot be triggered by hand. Undoing it requires Global Administrator and no lesser role is offered, while the device-side reversals sit at the ordinary operator tier. Record in the runbook rather than in your head which named individuals can obtain the role out of hours, how long your privileged access process takes to grant it, and who they call if that process is itself unavailable. Then exercise the elevation once, on a weekday, so the first time it runs is not during a containment.
Rollback
One step in this sheet is disruptive by design, which is the containment in the end-to-end test, and its blast radius is the whole onboarded fleet. Everything else is proof rather than change, so rollback is otherwise narrow. Discovery mode returns to basic through the same setting, at the cost of the containment prerequisite. A device group’s remediation level is a dropdown in both directions, remembering that changes take minutes to hours to propagate. Mailbox audit customisation is reversible by restoring the default set, and the previous customisation is not recoverable afterwards, so record what was there before you change it.
The exclusions are the part to be careful with, because removing one is immediate and re-adding it is a new object with a new note and no history. Take a copy of the register before editing. And the complete stop is not a setting at all: opting out of disruption entirely is a support case raised with the subject Attack disruption opt-out, after which alerts continue to arrive and no automated actions are taken. Treat that as an incident-grade decision with an owner, not as configuration.
Completion checklist
The coverage grid from step 1 exists in writing and names which actions this tenant cannot execute. Device discovery is standard and its scoping is confirmed as either all devices or a deliberately recorded tag set. Every device group’s remediation level has been read, the ungrouped default group has been set deliberately, and any group at no automated response is in the register with a reason. Domain controller auditing passes per area, the health issues are clear or explained by the known issue, and the 1644 diagnostic cleanup has been done. The action account question is settled for the sensor generation you actually run. The Microsoft 365 connector reads connected with every component selected and has been reconnected if it predates this year. Organisation level mail auditing is on, no mailbox has drifted off the default audit set, and no mailbox is bypassing audit. The exclusion register exists with owners, reasons and review dates, and the portal matches it. At least one incident notification rule has delivered a test message. The consolidated readback runs clean and prints its manual gaps. And the end-to-end test has been performed on disposable assets with both actions reversed.
Schedule these rather than ticking them. The exclusion review, because nothing expires an exclusion and no interface will surface a stale one. And a re-read of this configuration after 1 September 2026, because the automation level that step 3 audits is also the automated investigation setting, and Microsoft has not said what it governs once investigations stop running for endpoint.
Response is now configured as deliberately as this platform permits, which is to say the decisions are recorded and the prerequisites are proven, even though the acting itself remains outside your approval. What is left is the part of the platform your own team builds on rather than configures: the schema every one of these detections is written against, and the detection engineering plane that turns a query into something that acts. That is the schema article.
Defender XDR
‹ Previous: [D 7.2] The Response Fabric: Incidents, Attack Disruption, and the End of AIR
Next: [D 7.3] The Schema Is the Product: Advanced Hunting and Custom Detections ›




