Configure Defender Vulnerability Management, discover exposed assets, assess vulnerabilities by exploitability and business impact, create remediation tasks, track remediation progress, evaluate security baselines, and build a vulnerability management dashboard.
Defender Vulnerability Management (DVM) provides continuous asset visibility and risk-based vulnerability assessments. Unlike traditional scanning tools that flood you with thousands of CVEs ranked by generic CVSS scores, DVM uses real-time threat intelligence, exploit predictions, and business context to prioritize the vulnerabilities that actually matter. It integrates natively with Microsoft Defender for Endpoint, leveraging the existing sensor to provide agentless vulnerability discovery without additional network scanning infrastructure.
An enterprise organization with 5,000 endpoints discovers 12,000 CVEs across their estate. Traditional CVSS scoring ranks 3,000 of them as “Critical” (CVSS ≥ 9.0), leaving the vulnerability management team overwhelmed. By enabling Defender Vulnerability Management’s risk-based scoring. which factors in exploit availability, active threat campaigns, exposed attack surfaces, and business-critical asset context. the true priority list shrinks to 200 exploitable vulnerabilities with exposed attack paths. The team remediates those 200 in two weeks and reduces their organization’s exposure score by 40%.
Traditional vulnerability management is broken. teams drown in thousands of CVEs without knowing which ones attackers will actually exploit. According to research, fewer than 5% of published CVEs are ever exploited in the wild, yet CVSS alone cannot distinguish between a theoretical risk and an actively weaponized vulnerability. Defender Vulnerability Management solves this by combining Microsoft’s threat intelligence, exploit prediction models, and real-time attack surface data to surface the vulnerabilities that represent genuine risk. The result is fewer patches, faster remediation, and measurably reduced exposure.
The Vulnerability Management dashboard provides a single-pane view of your organization’s exposure score, vulnerable devices, top security recommendations, and remediation activity. Start here to understand your current vulnerability posture.
# WHAT: Query the Defender Vulnerability Management exposure and secure scores via the MDE API
# WHY: Programmatically track your organization's vulnerability posture over time
# for dashboards, automated reporting, and trend analysis
# PREREQUISITES: Requires an Entra ID app registration with Machine.Read.All permission
# in the WindowsDefenderATP resource (Microsoft Defender for Endpoint API)
$tenantId = "YOUR_TENANT_ID"
$clientId = "YOUR_CLIENT_ID"
$clientSecret = "YOUR_CLIENT_SECRET"
# Authenticate using OAuth 2.0 client credentials flow
# The scope targets the MDE API (securitycenter.microsoft.com)
$body = @{
grant_type = "client_credentials"
client_id = $clientId
client_secret = $clientSecret
scope = "https://api.securitycenter.microsoft.com/.default"
}
$token = (Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" `
-Method POST -Body $body).access_token
$headers = @{ Authorization = "Bearer $token" }
# Get exposure score (0-100, LOWER is better)
# The exposure score reflects overall vulnerability posture factoring in:
# exploitability, internet exposure, active threats, and device criticality
# Refreshes every ~4 hours; don't expect instant changes after patching
$exposure = Invoke-RestMethod -Uri "https://api.securitycenter.microsoft.com/api/exposureScore" `
-Headers $headers
Write-Host "Exposure Score: $($exposure.score)" -ForegroundColor Yellow
# Get secure score for devices (0-100, HIGHER is better)
# Measures security configuration hygiene: OS updates, security features enabled,
# firewall status, BitLocker, credential guard, etc.
$secureScore = Invoke-RestMethod -Uri "https://api.securitycenter.microsoft.com/api/configurationScore" `
-Headers $headers
Write-Host "Secure Score for Devices: $($secureScore.score)" -ForegroundColor CyanThe software inventory provides a complete view of all software installed across your managed devices, including version numbers, vendor details, known vulnerabilities, and end-of-life status.
// WHAT: Comprehensive software inventory with vulnerability counts per application
// WHY: Identifies which installed software carries the most known CVEs,
// helping prioritize patch cycles and EOL software replacement
// TABLE: DeviceTvmSoftwareInventory - all software detected on MDE-onboarded devices
// KEY FIELDS:
// SoftwareName / SoftwareVendor - the application and its publisher
// SoftwareVersion - installed version (may differ across devices)
// EndOfSupportStatus - "EOS" if past end-of-life (no more security patches)
// EndOfSupportDate - the actual EOL date
// JOIN: DeviceTvmSoftwareVulnerabilities - maps software to known CVEs
// OUTPUT: Software name, vendor, device count, vulnerability count, and installed versions
DeviceTvmSoftwareInventory
| summarize DeviceCount=dcount(DeviceId), Versions=make_set(SoftwareVersion)
by SoftwareName, SoftwareVendor
| join kind=leftouter (
DeviceTvmSoftwareVulnerabilities
| summarize VulnCount=dcount(CveId) by SoftwareName
) on SoftwareName
| project SoftwareName, SoftwareVendor, DeviceCount, VulnCount, Versions
| order by VulnCount desc
// WHAT: Find end-of-life software still installed on managed devices
// WHY: EOL software receives NO security patches - any new CVE is permanently unpatched.
// This is a top audit finding for PCI-DSS, ISO 27001, and SOC2 compliance.
// EndOfSupportStatus values: "EOS" (end of support) or empty (still supported)
DeviceTvmSoftwareInventory
| where EndOfSupportStatus == "EOS"
| summarize DeviceCount=dcount(DeviceId) by SoftwareName, SoftwareVersion, SoftwareVendor
| order by DeviceCount desc
// WHAT: Find software past its end-of-support date with no vendor patches available
// WHY: These represent permanent vulnerabilities requiring compensating controls
// (network segmentation, application whitelisting) or replacement
DeviceTvmSoftwareInventory
| where isnotempty(EndOfSupportDate) and EndOfSupportDate < now()
| summarize AffectedDevices=dcount(DeviceId) by SoftwareName, SoftwareVersion
| order by AffectedDevices descNot all CVEs are equal. DVM scores vulnerabilities by factoring in exploit availability, active threat campaigns, internet exposure, and device criticality. giving you a risk-based priority that goes far beyond generic CVSS.
// WHAT: Find exploitable vulnerabilities on internet-facing devices
// WHY: Internet-facing + exploit available = highest real-world risk.
// These are the CVEs attackers will target first in any campaign.
// TABLE: DeviceTvmSoftwareVulnerabilities - maps devices to CVEs
// KEY FIELDS:
// IsExploitAvailable - true/false: whether a public exploit exists (Metasploit, PoC, etc.)
// CveId - the CVE identifier (e.g., CVE-2024-12345)
// VulnerabilitySeverityLevel - Critical | High | Medium | Low (based on CVSS + DVM scoring)
// CvssScore - CVSS v3 base score (0.0-10.0):
// 9.0-10.0 = Critical, 7.0-8.9 = High, 4.0-6.9 = Medium, 0.1-3.9 = Low
// JOIN: DeviceInfo (IsInternetFacing = true) to focus on publicly exposed devices
// OUTPUT: CVEs with exploit available on internet-facing devices, sorted by severity
DeviceTvmSoftwareVulnerabilities
| where IsExploitAvailable == true
| join kind=inner (
DeviceInfo
| where IsInternetFacing == true
| distinct DeviceId, DeviceName
) on DeviceId
| summarize ExposedDevices=dcount(DeviceId) by CveId, SoftwareName,
VulnerabilitySeverityLevel, CvssScore
| order by CvssScore desc, ExposedDevices desc
// WHAT: Compare CVSS severity scores vs actual exploitability to build risk categories
// WHY: Only ~5% of CVEs are ever exploited in the wild. A CVSS 9.0 vulnerability
// with no known exploit is lower real-world risk than a CVSS 7.0 with a
// Metasploit module. This query creates actionable priority buckets.
// RiskCategory logic:
// Exploit available + CVSS >= 9.0 = "Critical. Patch Now" (immediate action)
// Exploit available + CVSS >= 7.0 = "High. Patch This Week" (urgent)
// No exploit + CVSS >= 9.0 = "High CVSS but No Exploit" (monitor, lower priority)
// Everything else = "Monitor" (track but deprioritize)
DeviceTvmSoftwareVulnerabilities
| summarize
TotalDevices=dcount(DeviceId),
ExploitAvailable=max(toint(IsExploitAvailable))
by CveId, VulnerabilitySeverityLevel, CvssScore
| extend RiskCategory = case(
ExploitAvailable == 1 and CvssScore >= 9.0, "Critical. Patch Now",
ExploitAvailable == 1 and CvssScore >= 7.0, "High. Patch This Week",
ExploitAvailable == 0 and CvssScore >= 9.0, "High CVSS but No Exploit",
"Monitor")
| summarize CVEs=count(), Devices=sum(TotalDevices) by RiskCategory
| order by CVEs desc
// WHAT: Find exploitable vulnerabilities affecting 5+ devices in the environment
// WHY: Wide-impact exploitable CVEs represent the highest organizational risk;
// patching these delivers the largest exposure score reduction per patch cycle
DeviceTvmSoftwareVulnerabilities
| where IsExploitAvailable == true
| summarize AffectedDevices=dcount(DeviceId), Software=make_set(SoftwareName)
by CveId, CvssScore, VulnerabilitySeverityLevel
| where AffectedDevices > 5
| order by CvssScore descSecurity baselines ensure your devices meet configuration standards from CIS Benchmarks and Microsoft security recommendations. DVM continuously assesses device configurations against these benchmarks and highlights non-compliant settings.
// Devices with misconfigured security settings
DeviceTvmSecureConfigurationAssessment
| where IsCompliant == false
| summarize NonCompliantSettings=count() by DeviceName, DeviceId
| order by NonCompliantSettings desc
| take 20
// Top misconfigured settings across all devices
DeviceTvmSecureConfigurationAssessment
| where IsCompliant == false
| summarize AffectedDevices=dcount(DeviceId) by ConfigurationId,
ConfigurationName, ConfigurationCategory
| order by AffectedDevices desc
| take 15
// Compliance rate by configuration category
DeviceTvmSecureConfigurationAssessment
| summarize
Total=count(),
Compliant=countif(IsCompliant == true),
NonCompliant=countif(IsCompliant == false)
by ConfigurationCategory
| extend ComplianceRate = round(todouble(Compliant) / Total * 100, 1)
| order by ComplianceRate ascBrowser extensions are a growing attack vector. Malicious or overprivileged extensions can steal credentials, exfiltrate data, and inject content into web pages. DVM inventories all browser extensions across your managed devices and flags risky ones.
// List all browser extensions with device counts
DeviceTvmBrowserExtensions
| summarize InstalledDevices=dcount(DeviceId) by ExtensionName,
BrowserName, ExtensionVersion, ExtensionVendor
| order by InstalledDevices desc
// Find extensions with high-risk permissions
DeviceTvmBrowserExtensions
| where PermissionRisk == "High"
| summarize InstalledDevices=dcount(DeviceId),
Permissions=make_set(ExtensionPermissions)
by ExtensionName, BrowserName, ExtensionVendor
| order by InstalledDevices desc
// Extensions requesting access to all URLs
DeviceTvmBrowserExtensions
| where ExtensionPermissions has "allUrls" or ExtensionPermissions has "<all_urls>"
| summarize InstalledDevices=dcount(DeviceId) by ExtensionName,
ExtensionVendor, BrowserName
| order by InstalledDevices descRemediation activities bridge the gap between the security team (who identifies vulnerabilities) and the IT operations team (who patches them). DVM lets you create remediation requests with deadlines, assign them to teams, and track completion.
# Create a remediation activity via MDE API
$body = @{
title = "Update Chrome to latest version"
description = "Chrome 120.x has 3 critical CVEs with active exploits. Update to 121+ across all devices."
priority = "High"
dueDate = (Get-Date).AddDays(7).ToString("yyyy-MM-ddTHH:mm:ssZ")
category = "Software"
relatedComponent = "Google Chrome"
fixedAssetIds = @() # Targets all affected devices
} | ConvertTo-Json
$remediation = Invoke-RestMethod `
-Uri "https://api.securitycenter.microsoft.com/api/remediationTasks" `
-Headers $headers `
-Method POST `
-Body $body `
-ContentType "application/json"
Write-Host "Remediation task created: $($remediation.id)" -ForegroundColor Green
# List all active remediation activities
$tasks = Invoke-RestMethod `
-Uri "https://api.securitycenter.microsoft.com/api/remediationTasks" `
-Headers $headers
$tasks.value | Select-Object id, title, status, priority, dueDate | Format-TableAfter creating remediation activities, monitor their status to ensure patches are applied, exposure scores decrease, and your SLAs are met.
// Track vulnerability count trend over time
DeviceTvmSoftwareVulnerabilities
| where TimeGenerated > ago(30d)
| summarize VulnCount=dcount(CveId),
AffectedDevices=dcount(DeviceId) by bin(TimeGenerated, 1d)
| render timechart
// Verify patching: check if specific CVE is still present
DeviceTvmSoftwareVulnerabilities
| where CveId == "CVE-2024-1234"
| summarize RemainingDevices=dcount(DeviceId) by SoftwareName, SoftwareVersion
| order by RemainingDevices desc
// Exposure score trend (requires custom logging via API)
// Alternative: use the DVM dashboard's built-in trend chart
DeviceTvmSoftwareVulnerabilities
| where IsExploitAvailable == true
| summarize ExploitableVulns=dcount(CveId),
ExposedDevices=dcount(DeviceId) by bin(TimeGenerated, 1d)
| render timechartSecurity recommendations are prioritized actions that DVM identifies to reduce your exposure. Each recommendation includes the expected exposure reduction, affected devices, and remediation steps. You can accept, dismiss, or create exceptions for each recommendation.
// Top security recommendations by affected device count
DeviceTvmSecureConfigurationAssessment
| where IsCompliant == false and IsApplicable == true
| summarize AffectedDevices=dcount(DeviceId) by ConfigurationId,
ConfigurationName, ConfigurationCategory, ConfigurationSubcategory
| order by AffectedDevices desc
| take 20
// Recommendations grouped by category
DeviceTvmSecureConfigurationAssessment
| where IsCompliant == false
| summarize Recommendations=dcount(ConfigurationId),
AffectedDevices=dcount(DeviceId)
by ConfigurationCategory
| order by AffectedDevices descCreate a Sentinel workbook (or Defender advanced hunting dashboard) with KQL tiles that give executives and security teams a comprehensive view of vulnerability management metrics, trends, and remediation velocity.
// Tile 1: Vulnerability Trend (last 30 days)
DeviceTvmSoftwareVulnerabilities
| where TimeGenerated > ago(30d)
| summarize Vulnerabilities=dcount(CveId) by bin(TimeGenerated, 1d),
VulnerabilitySeverityLevel
| render timechart
// Tile 2: Most Vulnerable Software (top 10)
DeviceTvmSoftwareVulnerabilities
| summarize CVEs=dcount(CveId), Devices=dcount(DeviceId) by SoftwareName
| top 10 by CVEs
| render barchart
// Tile 3: Remediation Velocity
// Track how quickly vulnerabilities are being patched
DeviceTvmSoftwareVulnerabilities
| where TimeGenerated > ago(30d)
| where IsExploitAvailable == true
| summarize ExploitableVulns=dcount(CveId) by bin(TimeGenerated, 1d)
| render timechart
// Tile 4: Exposure Score Over Time
// Uses custom logging. alternative: screenshot from dashboard
DeviceTvmSoftwareVulnerabilities
| summarize TotalVulns=dcount(CveId),
CriticalVulns=dcountif(CveId, VulnerabilitySeverityLevel == "Critical"),
ExploitableVulns=dcountif(CveId, IsExploitAvailable == true)
by bin(TimeGenerated, 1d)
| render timechart
// Tile 5: Security Baseline Compliance Rate
DeviceTvmSecureConfigurationAssessment
| summarize
Total=count(),
Compliant=countif(IsCompliant == true)
by ConfigurationCategory
| extend CompliancePercent = round(todouble(Compliant) / Total * 100, 1)
| render barchart
// Tile 6: Devices by Vulnerability Count
DeviceTvmSoftwareVulnerabilities
| summarize VulnCount=dcount(CveId) by DeviceName
| extend RiskBucket = case(
VulnCount > 100, "Critical (>100)",
VulnCount > 50, "High (50-100)",
VulnCount > 20, "Medium (20-50)",
"Low (<20)")
| summarize Devices=count() by RiskBucket
| render piechartDVM. Vulnerability Management DashboardReview what you’ve built and plan your ongoing vulnerability management operations.
# Recommended cadence for vulnerability management operations
# Daily: Check for new critical/exploitable vulnerabilities
# Weekly: Review remediation progress, update ticket statuses
# Monthly: Executive dashboard review, SLA compliance report
# Quarterly: Full baseline assessment, exception review, policy updates
# Quick daily check script
$headers = @{ Authorization = "Bearer $token" }
# Get new vulnerabilities discovered in last 24 hours
$newVulns = Invoke-RestMethod `
-Uri "https://api.securitycenter.microsoft.com/api/vulnerabilities?`$filter=publishedOn gt $(
(Get-Date).AddDays(-1).ToString('yyyy-MM-ddTHH:mm:ssZ'))" `
-Headers $headers
Write-Host "New vulnerabilities in last 24h: $($newVulns.value.Count)" -ForegroundColor Yellow
$newVulns.value | Where-Object { $_.exploitInKit -eq $true } |
Select-Object id, name, severity | Format-Table| Resource | Description |
|---|---|
| Defender Vulnerability Management overview | Product overview and feature documentation |
| Vulnerability management dashboard | Understand exposure score and dashboard metrics |
| Software inventory | Browse and analyze installed software across devices |
| Vulnerabilities in your organization | Assess and prioritize CVEs by risk |
| Security recommendations | Prioritized actions to reduce exposure |
| Remediation and exception | Create and track remediation activities |
| Browser extensions assessment | Assess risky browser extensions |
| MDE APIs | Programmatic access to vulnerability management data |