Objective
Run all 6 hardening validation queries from Module 9, subsection 9.6, against your Sentinel workspace. Document results, identify hardening gaps, and create an action plan.
Required: Sentinel workspace with SigninLogs, OfficeActivity, DeviceEvents, and DeviceInfo tables populated.
Step 1: Run each validation query
Open Sentinel → Logs. Run each query, record the result, and assess against the expected outcome.
V-001: MFA enforcement
SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| where AuthenticationRequirement == "singleFactorAuthentication"
| where UserPrincipalName !in ("breakglass1@yourdomain.com", "breakglass2@yourdomain.com")
| summarize count() by UserPrincipalName, AppDisplayNameExpected: Zero rows (all sign-ins require MFA). Any rows = users bypassing MFA.
V-002: Legacy authentication block
SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| where ClientAppUsed in ("IMAP", "POP3", "SMTP", "Exchange ActiveSync")
| summarize count() by ClientAppUsed, UserPrincipalNameExpected: Zero rows. Any rows = legacy protocols succeeding despite the block.
V-003: External forwarding block
OfficeActivity
| where TimeGenerated > ago(7d)
| where Operation == "New-InboxRule"
| where Parameters has "ForwardTo" or Parameters has "RedirectTo"
| extend ForwardDest = extract(@"@([a-zA-Z0-9.-]+)", 1, tostring(Parameters))
| where ForwardDest !endswith "yourdomain.com"
| where isnotempty(ForwardDest)
| project TimeGenerated, UserId, ParametersExpected: Zero rows if external forwarding is blocked at the transport level.
V-004: ASR rule status
DeviceEvents
| where TimeGenerated > ago(7d)
| where ActionType startswith "Asr"
| summarize
Blocked = countif(ActionType endswith "Blocked"),
Audited = countif(ActionType endswith "Audited")
by ActionTypeReview: Rules with "Audited" only should be transitioned to Block mode after tuning.
V-005: Device compliance
DeviceInfo
| where TimeGenerated > ago(1d)
| summarize arg_max(TimeGenerated, *) by DeviceName
| summarize
Total = count(),
Compliant = countif(IsCompliant == true),
NonCompliant = countif(IsCompliant != true)
| extend ComplianceRate = round(100.0 * Compliant / Total, 1)Target: Above 90% compliance rate.
V-006: Tamper protection
DeviceEvents
| where TimeGenerated > ago(30d)
| where ActionType == "TamperProtection"
| summarize Attempts = count() by DeviceName
| sort by Attempts descExpected: Zero rows. Any results indicate tamper attempts requiring investigation.
Step 2: Document findings
Complete this table with your results:
| Query | Expected | Actual result | Gap? | Root cause | Priority |
|---|---|---|---|---|---|
| V-001 MFA | 0 rows | ||||
| V-002 Legacy auth | 0 rows | ||||
| V-003 Forwarding | 0 rows | ||||
| V-004 ASR | All Block | ||||
| V-005 Compliance | >90% | ||||
| V-006 Tamper | 0 rows |
Step 3: Create remediation plan
For each gap:
- Control: Which hardening control is not functioning?
- Root cause: Misconfiguration, exclusion that should not exist, or control not deployed?
- Remediation: Specific action to close the gap
- Owner: Who will implement?
- Deadline: When will it be resolved?
- Verification: Which validation query confirms the fix worked?
Step 4: Schedule recurring validation
Add the 6 validation queries to your weekly operational cadence:
- When: Every Monday, first task of the shift
- Duration: 15-20 minutes
- Document: Record results in the hardening health log
- Escalate: Any new gap identified → immediate investigation
Verification checklist
- [ ] All 6 validation queries executed
- [ ] Results documented with root cause analysis for each gap
- [ ] Remediation plan created with owners and deadlines
- [ ] Weekly validation cadence scheduled
- [ ] Hardening health log template created