Microsoft Defender security

How to list vulnerable software in Microsoft Defender

List vulnerable software on each device with an advanced hunting query in PowerShell, review weaknesses in the Defender portal, or run Altivane's Vulnerable Software report for a workbook.

By the Published

To list vulnerable software in Microsoft Defender, query the DeviceTvmSoftwareVulnerabilities table in advanced hunting, which holds the vulnerable software on each device with its CVE, severity and the security update that fixes it. The table comes from Microsoft Defender for Endpoint, so only onboarded devices appear. It needs Defender for Endpoint Plan 2 or Defender Vulnerability Management; Defender for Business doesn't include it.

Choose the method that fits the job
MethodBest fit
PowerShellA CSV by device, program and CVE, up to 100,000 rows, from 1 advanced hunting query.
Admin centreWorking through programs and CVEs in the Defender portal, with the devices exposed.
AltivaneRecommended for recurring reviews, with every vulnerability on every device in a workbook.

Before you start

Use an account that can run advanced hunting in the Microsoft Defender portal. The PowerShell example requests ThreatHunting.Read.All, the only permission Microsoft lists for the hunting API; your organisation may require administrator consent.

Microsoft says a fix typically shows within 24 to 48 hours of the device reporting the new version, so a patch installed today can still show. Software without an official product code (CPE) isn't covered by vulnerability management. The examples read and export and change nothing.

Option 1

List vulnerable software with PowerShell

Install the module once, then connect, run the query through Microsoft Graph and export the rows.

PowerShell
# Install once, if the module is not already installed.
Install-Module Microsoft.Graph.Authentication -Scope CurrentUser
PowerShell
$ErrorActionPreference = 'Stop'
Connect-MgGraph -Scopes 'ThreatHunting.Read.All' -NoWelcome
try {
    $columns = 'DeviceName', 'OSPlatform', 'SoftwareVendor', 'SoftwareName', 'SoftwareVersion',
        'CveId', 'VulnerabilitySeverityLevel', 'RecommendedSecurityUpdate'
    $query = "DeviceTvmSoftwareVulnerabilities | project $($columns -join ', ')" +
        ' | order by DeviceName asc, SoftwareName asc'
    $body = @{ Query = $query } | ConvertTo-Json
    $uri = 'https://graph.microsoft.com/v1.0/security/runHuntingQuery'
    $request = @{ Method = 'POST'; Uri = $uri; Body = $body; ContentType = 'application/json' }
    $response = Invoke-MgGraphRequest @request
    $rows = @($response.results | ForEach-Object { [pscustomobject]$_ } | Select-Object $columns)
    if ($rows.Count -eq 0) {
        Write-Output 'Advanced hunting returned no vulnerable software.'
    } else {
        $rows | Export-Csv -Path './vulnerable-software.csv' -NoTypeInformation -Encoding utf8
        Write-Output "$($rows.Count) rows written to vulnerable-software.csv."
        if ($rows.Count -ge 100000) { Write-Warning 'Stopped at 100,000 rows: narrow the query.' }
    }
} finally {
    Disconnect-MgGraph | Out-Null
}

The file has 1 row for each device, program and CVE, so 1 old browser on 40 devices with 10 CVEs gives 400 rows. RecommendedSecurityUpdate names the update that fixes it, where the publisher has one. Microsoft returns at most 100,000 rows and 50 MB from 1 query, so on a large tenant the list can stop short; the script warns at 100,000 rows. To narrow it, add a where line to the query before project, by severity or device, such as | where VulnerabilitySeverityLevel == 'Critical' or | where DeviceName startswith 'lon-'.

Count vulnerable software across devices

Reconnect with Connect-MgGraph, then run a query that gives 1 row per program with how many devices and CVEs it has. The main export above disconnects when it finishes.

PowerShell
# Run while connected to Microsoft Graph with ThreatHunting.Read.All.
$query = 'DeviceTvmSoftwareVulnerabilities' +
    ' | summarize Devices = dcount(DeviceId), CVEs = dcount(CveId)' +
    ' by SoftwareVendor, SoftwareName | order by Devices desc'
$body = @{ Query = $query } | ConvertTo-Json
$uri = 'https://graph.microsoft.com/v1.0/security/runHuntingQuery'
$response = Invoke-MgGraphRequest -Method POST -Uri $uri -Body $body -ContentType 'application/json'
$response.results | ForEach-Object { [pscustomobject]$_ } | Select-Object -First 20

Option 2

Review vulnerable software in the Defender portal

  1. Sign in to the Microsoft Defender portal for the correct tenant.
  2. Go to Endpoints > Vulnerability management > Inventories and select the Software tab. In the newer layout it's under Exposure management > Vulnerability management > Inventories.
  3. Read Weaknesses and Exposed devices for each program, and filter by OS platform, weaknesses or tags such as end of support.
  4. Select a program and open its software page, then select Discovered vulnerabilities for its CVEs.
  5. For every CVE at once, open Weaknesses from the vulnerability management menu (Vulnerabilities in the newer layout) and export the list. Leave the pages without changing anything.

This suits working through the worst programs in Microsoft's own pages. The weaknesses export stops at 6,000 records and 64 KB, and the device view means opening each device, so for a full list by device, use PowerShell or Altivane.

Common questions

Why does the query return no rows?

The table is filled by Defender for Endpoint. If the organisation hasn't deployed it, or no device is onboarded, Microsoft says queries on the table return nothing. Check the licence too: Defender for Business doesn't include vulnerability management.

Why does a program show as vulnerable after it was updated?

Microsoft says a fix typically shows within 24 to 48 hours of the device reporting the new version. The software inventory updates every 3 to 4 hours and can't be forced. Wait 2 days, then run the export again before you chase the device's owner.

How do I find devices on Windows versions that no longer get updates?

Software on an unsupported Windows build may never get a fix. To find those devices in Intune, see how to find unsupported Windows versions in Intune.

Microsoft references

Technical references checked on 6 November 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.

Talk to us about Altivane

Questions, or pricing? Get in touch.

Contact us