In this module

AD7.5 Building the Complete Quarterly Report

5-6 hours · Module 7 · Free
Operational Objective
Throughout Modules AD1-AD6, you've built individual report sections: identity metrics (AD1), email protection stats (AD2), device compliance rates (AD3), data protection coverage (AD4), monitoring outcomes (AD5), and incident summaries (AD6). This subsection assembles them into the complete quarterly security posture report — a single document that demonstrates your security program's effectiveness with measurable outcomes. The report serves three audiences: your manager (program justification and resource needs), compliance (evidence of active security governance), and yourself (trend tracking and improvement planning). After completing this subsection, the quarterly report takes 20 minutes to produce because the data collection is scripted and the template is established.
Deliverable: The complete 7-section quarterly security posture report template with automated data collection scripts — ready to produce every quarter in under 30 minutes.
Estimated completion: 30 minutes
QUARTERLY SECURITY POSTURE REPORT — 7 SECTIONS 1. EXECUTIVE 4 sentences All 7 layers For: everyone 2. IDENTITY MFA, CA, risk AD1 metrics 3. EMAIL Phishing, DMARC AD2 metrics 4. DEVICES Compliance % AD3 metrics 5. DATA Labels, DLP AD4 metrics 6. INCIDENTS TP/FP, response AD5-6 metrics 7. NEXT STEPS Improvements, budget AD7 roadmap CONSOLIDATED DATA COLLECTION SCRIPT One PowerShell script collects all 7 sections of data in 5 minutes → paste into template → report complete in 20 minutes Scripts from AD1 (MFA), AD3 (compliance), AD4 (DLP), AD5 (Secure Score, sign-ins) consolidated into Get-QuarterlyReport.ps1

Figure AD7.5 — The quarterly report has 7 sections covering every layer of the security program. A consolidated PowerShell script collects the data for all sections in 5 minutes. The template is filled in manually from the script output — total production time under 30 minutes.

The consolidated data collection script

Save this as C:\SecurityScripts\Get-QuarterlyReport.ps1. Run it at the start of each quarter to collect all report data:

# Get-QuarterlyReport.ps1 — Quarterly Security Posture Data Collection
# Run at the start of each quarter to collect data for the report

param(
    [int]$DaysBack = 90  # Default: last quarter (90 days)
)

$startDate = (Get-Date).AddDays(-$DaysBack).ToString("yyyy-MM-ddTHH:mm:ssZ")
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "  QUARTERLY SECURITY REPORT DATA" -ForegroundColor Cyan
Write-Host "  Period: Last $DaysBack days" -ForegroundColor Cyan
Write-Host "  Generated: $(Get-Date -Format 'dd MMM yyyy HH:mm')" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan

# Connect to all required services
Connect-MgGraph -Scopes "AuditLog.Read.All","SecurityEvents.Read.All","DeviceManagementManagedDevices.Read.All" -NoWelcome
Connect-ExchangeOnline -ShowBanner:$false

# --- SECTION 2: IDENTITY ---
Write-Host "`n--- SECTION 2: IDENTITY ---" -ForegroundColor Yellow
$allSignIns = Get-MgAuditLogSignIn -Filter "createdDateTime ge $startDate" -Top 5000
$riskySignIns = ($allSignIns | Where-Object { $_.RiskLevelDuringSignIn -notin @("none","hidden") }).Count
$caBlocked = ($allSignIns | Where-Object { $_.ConditionalAccessStatus -eq "failure" }).Count
Write-Host "Total sign-ins: $($allSignIns.Count)"
Write-Host "Risky sign-ins detected: $riskySignIns"
Write-Host "Sign-ins blocked by CA: $caBlocked"

# MFA coverage
$allUsers = Get-MgUser -All -Property UserPrincipalName,AccountEnabled | Where-Object { $_.AccountEnabled }
$mfaRegistered = 0
foreach ($u in $allUsers | Select-Object -First 50) {
    $methods = (Get-MgUserAuthenticationMethod -UserId $u.UserPrincipalName -ErrorAction SilentlyContinue).Count
    if ($methods -gt 1) { $mfaRegistered++ }
}
Write-Host "MFA registered (sample): $mfaRegistered / $($allUsers.Count) users"

# --- SECTION 3: EMAIL ---
Write-Host "`n--- SECTION 3: EMAIL ---" -ForegroundColor Yellow
Write-Host "Check manually: security.microsoft.com → Reports → Threat protection status"
Write-Host "Record: phishing blocked, malware blocked, user-reported, delivered phishing"

# --- SECTION 4: DEVICES ---
Write-Host "`n--- SECTION 4: DEVICES ---" -ForegroundColor Yellow
$devices = Get-MgDeviceManagementManagedDevice -All
$compliant = ($devices | Where-Object { $_.ComplianceState -eq "compliant" }).Count
$total = $devices.Count
$rate = if ($total -gt 0) { [math]::Round($compliant / $total * 100, 1) } else { 0 }
Write-Host "Total managed devices: $total"
Write-Host "Compliant: $compliant ($rate%)"
Write-Host "Non-compliant: $($total - $compliant)"

# --- SECTION 5: DATA ---
Write-Host "`n--- SECTION 5: DATA ---" -ForegroundColor Yellow
Write-Host "Check manually: purview.microsoft.com → Data Classification → Overview"
Write-Host "Record: labeled documents %, label distribution, DLP matches, overrides"

# DLP summary
Connect-IPPSSession -ShowBanner:$false
$dlpMatches = Get-DlpDetailReport -StartDate (Get-Date).AddDays(-$DaysBack) -EndDate (Get-Date) -ErrorAction SilentlyContinue
if ($dlpMatches) {
    Write-Host "DLP matches: $($dlpMatches.Count)"
    $dlpMatches | Group-Object PolicyAction | Select-Object Name, Count | Format-Table
}

# --- SECTION 6: SECURE SCORE ---
Write-Host "`n--- SECTION 6: SECURE SCORE ---" -ForegroundColor Yellow
$score = Get-MgSecuritySecureScore -Top 1
$pct = [math]::Round($score.CurrentScore / $score.MaxScore * 100, 1)
Write-Host "Current: $($score.CurrentScore) / $($score.MaxScore) ($pct%)"

# --- SECTION 7: INCIDENTS ---
Write-Host "`n--- SECTION 7: INCIDENTS ---" -ForegroundColor Yellow
Write-Host "Check manually: weekly security log for incident count, classification"
Write-Host "Record: TP count, FP count, BTP count, mean time to detect, mean time to contain"

Write-Host "`n========================================" -ForegroundColor Green
Write-Host "  DATA COLLECTION COMPLETE" -ForegroundColor Green
Write-Host "  Paste results into report template" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green

Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue

The complete report template

QUARTERLY SECURITY POSTURE REPORT
[Organization Name]
Q[X] [Year] | Prepared by: [Name] | Date: [Date]

1. EXECUTIVE SUMMARY
[4 sentences covering all layers. Example:]
"This quarter, [Organization] maintained robust security across all
layers: [X] credential attacks blocked by MFA and conditional access,
[X] phishing emails blocked by Defender for Office 365, [X]%
device compliance rate with BitLocker encryption verified, and [X]%
of documents classified with sensitivity labels. [X] security
incidents were detected and contained through weekly monitoring,
with mean time to detect of [X] hours. Secure Score maintained at
[X]% (industry benchmark: [X]%). All controls operate within the
existing E3 licence at no additional cost."

2. IDENTITY (Module AD1)
- MFA coverage: [X]% of active users
- Credential attacks blocked: [X] (CA failures from unfamiliar sources)
- Risky sign-ins detected: [X] (investigated during weekly review)
- Compromised accounts: [X] (contained via AD6.2 procedure)
- Conditional access policies active: [X] (CA001-CA003)
- Trend: [stable/improved/declined] vs last quarter

3. EMAIL (Module AD2)
- Phishing emails blocked: [X]
- Safe Links clicks blocked: [X]
- Malware attachments blocked: [X]
- User-reported suspicious emails: [X]
- Phishing emails delivered (missed by filters): [X]
- DMARC status: [p=none/quarantine/reject]
- Trend: [stable/improved/declined] vs last quarter

4. DEVICES (Module AD3)
- Compliance rate: [X]%
- Encryption coverage: [X]% (BitLocker verified)
- Unmanaged device access blocked: [X]
- Non-compliant devices remediated: [X]
- Exceptions: [X] active exceptions (reviewed quarterly)
- Trend: [stable/improved/declined] vs last quarter

5. DATA (Module AD4)
- Label adoption: [X]% of documents classified
- Label distribution: Public [X]%, Internal [X]%, Confidential [X]%,
  Highly Confidential [X]%
- DLP matches: [X] (blocked: [X], overridden: [X])
- External sharing: anonymous links disabled, [X] external users active
- Stale external access removed: [X] users this quarter
- Trend: [stable/improved/declined] vs last quarter

6. INCIDENTS AND MONITORING (Modules AD5-AD6)
- Weekly security reviews conducted: [X]/13 (target: 13/13)
- Incidents detected: [X] total ([X] TP, [X] FP, [X] BTP)
- Mean time to detect: [X] hours
- Mean time to contain: [X] minutes
- Secure Score: [X]% (vs [X]% last quarter)
- Notable incidents: [brief summary of any TP incidents]

7. NEXT STEPS AND RECOMMENDATIONS
- Completed improvements: [list from post-incident reviews]
- In-progress improvements: [list with timelines]
- Recommendations for next quarter: [prioritized list]
- E5 evaluation: [status — see AD7.9 for full business case]
- Budget requests: [if any]
- Governance status: [X]/4 policies approved, IRP tested [date]

APPENDIX: Data Sources
- Identity: Entra ID sign-in logs, Get-MgAuditLogSignIn
- Email: Defender portal → Reports → Threat protection status
- Devices: Intune compliance dashboard, Get-MgDeviceManagementManagedDevice
- Data: Purview Data Classification dashboard, Get-DlpDetailReport
- Secure Score: Get-MgSecuritySecureScore
- Incidents: Weekly security log (C:\SecurityScripts\WeeklySecurityLog.csv)

Report production workflow

Day 1 of the quarter (30 minutes):

  1. Run Get-QuarterlyReport.ps1 — automated data collection (5 min)
  2. Open the report template — copy from the previous quarter's report (1 min)
  3. Update Section 1 (executive summary) with the new numbers (5 min)
  4. Update Sections 2-5 with automated data + manual portal checks (10 min)
  5. Update Section 6 from the weekly security log (5 min)
  6. Update Section 7 with improvements completed and planned (4 min)

The first quarterly report takes 45-60 minutes (building the template from scratch). Subsequent reports take 20-30 minutes (updating numbers in an existing template). The PowerShell script does the heavy lifting — you're mostly copying numbers from the script output into the report.

Save each quarter's report as a separate file: SecurityReport-Q1-2026.docx, SecurityReport-Q2-2026.docx. The collection of quarterly reports demonstrates continuous monitoring and improvement over time — auditors and management can see the progression.

Presenting the quarterly report to management

The report document is the artifact. The presentation is the conversation. Keep the presentation to 5-10 minutes:

Open with the executive summary (1 minute). Read or paraphrase the 4-sentence summary. This gives management the complete picture in 30 seconds.

Highlight one achievement (1 minute). "This quarter, our MFA enforcement blocked 89 credential attacks. Without MFA, any of these could have resulted in a compromised account." Choose the metric that best demonstrates value.

Flag one concern (1 minute). "Our Secure Score dropped by 4 points due to a temporary CA policy change. We identified and corrected it within the weekly review cycle." Transparency about issues builds trust — management respects honesty about challenges more than a presentation where everything is perfect.

Present next steps (2 minutes). "Priorities for next quarter: implement MFA registration restrictions, evaluate Entra ID P2 add-on, deploy phishing simulation." Each next step is justified by data from this quarter's report.

Answer questions (5 minutes). Management typically asks: "Are we secure?" (Yes — here are the metrics), "What's our biggest risk?" (The specific gap from Section 9), "What do we need to spend?" (Reference the E5 business case if applicable, otherwise "nothing — E3 covers everything").

Don't read the full report in the meeting — send it in advance and use the meeting for the summary and discussion. The report is the evidence; the meeting is the conversation.

Report distribution list

Send the quarterly report to:

Your direct manager: Full report. They need all 7 sections for their own reporting to senior management.

Senior management / board (if applicable): Executive summary only (Section 1) plus Section 7 (Next Steps and budget recommendations). They don't need the technical detail — they need the outcome and the resource request.

IT team colleagues: Sections 2-6 (technical detail). They may identify data they can contribute or corrections to metrics from their areas.

DPO / Legal (if applicable): Section 6 (incidents) and any GDPR-relevant findings. They need awareness of incidents that may have regulatory implications.

Auditor (on request): Full report with all sections. The quarterly report is primary evidence for active security monitoring and program management.

Compliance Myth: "Quarterly reporting is excessive — an annual report is sufficient"
An annual report tells management what happened 6-12 months ago. By the time they see the data, any issues are long past. A quarterly report tells management what happened in the last 90 days — recent enough to act on, frequent enough to show trends, and regular enough to demonstrate continuous monitoring. Quarterly reporting takes 20-30 minutes four times a year (2 hours total). The return: management visibility, audit evidence, trend data, and justification for security investment. Annual reporting provides the same documentation value at 25% of the frequency — which means issues are discovered 3x slower and improvement trends are invisible until year-end.
Decision point

Your first quarterly report shows: Secure Score 67%, compliance rate 97%, 0 delivered phishing, 2 incidents (both contained within 30 minutes), all on E3. Your manager asks: "Can you benchmark this against industry?" How do you respond?

Option A: "I'll research industry benchmarks and add them to the next report."

Option B: "The Secure Score comparison tab in the Defender portal shows our score against similar-sized organizations in our industry. Currently we're at 67% vs an industry average of 52% — we're above average. For the other metrics, formal industry benchmarks are limited for SMBs, but the directional data is clear: 0 delivered phishing, 97% compliance, and sub-30-minute containment represent a mature security posture for an organization our size. I'll add the Secure Score benchmark to Section 6 of future reports."

The correct answer is Option B. Use the data you have (Secure Score benchmarking is built into the portal). Acknowledge the limitations of broader benchmarking for SMBs. The directional evidence (zero delivered phishing, high compliance, fast containment) tells the story even without precise industry comparisons.

Try it: Produce your first quarterly report

1. Run Get-QuarterlyReport.ps1 and record the output 2. Copy the report template into a Word document 3. Fill in all 7 sections with your real data (or estimated data if this is your first quarter) 4. Write the executive summary — 4 sentences covering all layers 5. Add at least 2 items to Section 7 (next steps) 6. Save as SecurityReport-Q[X]-2026.docx 7. Send to your manager

Time the exercise. Your target: under 30 minutes for future reports. The first one may take 45-60 minutes as you establish the template and data sources.

Your quarterly report shows Secure Score dropped from 67% to 63% this quarter. All other metrics are stable. What should you include in Section 7 (Next Steps)?
"Secure Score decreased by 4 points due to [specific cause identified in AD5.7 weekly checks]. Corrective action taken on [date]: [description]. Score has recovered to [X]% as of report date. Recommendation: add Secure Score stability to the weekly review checklist to catch drops within 7 days." — Correct. The report identifies the issue, documents the resolution, and recommends a process improvement. This demonstrates active management of the security posture.
"Secure Score dropped — will investigate" — Too vague. The quarterly report should include root cause and corrective action, not a promise to investigate.
Don't mention it — all other metrics are stable — The score drop is a finding that should be transparently reported. Hiding negative data undermines the report's credibility.
"Microsoft changed the scoring — not our fault" — Verify before attributing. Check the Secure Score history to confirm whether it was a Microsoft change or a configuration change.

You're reading the free modules of M365 Security: From Admin to Defender

The full course continues with advanced topics, production detection rules, worked investigation scenarios, and deployable artifacts.

View Pricing See Full Syllabus