All scripts
Governance 616
Get-DefenderDeviceRiskReport
Pulls every device's risk score from Microsoft Defender for Endpoint via Graph Security API and flags anything above Medium, a fast weekly triage list before you open the full portal.
Get-DefenderDeviceRiskReport.ps1
<#
.SYNOPSIS
Get-DefenderDeviceRiskReport.ps1 - Reports device risk scores from Microsoft Defender for Endpoint.
.DESCRIPTION
Queries the Defender for Endpoint API directly for every onboarded machine's
current risk score, health status and exposure level, and highlights anything
at Medium risk or above. Requires an app registration with Machine.Read.All
application permission on the WindowsDefenderATP API.
.AUTHOR
Shehryar Hassan
.EXAMPLE
.\Get-DefenderDeviceRiskReport.ps1 -TenantId "..." -ClientId "..." -ClientSecret (Read-Host -AsSecureString)
#>
param(
[Parameter(Mandatory=$true)]
[string]$TenantId,
[Parameter(Mandatory=$true)]
[string]$ClientId,
[Parameter(Mandatory=$true)]
[securestring]$ClientSecret,
[Parameter(Mandatory=$false)]
[string]$OutputPath = ".\DeviceRiskReport.csv"
)
Write-Host "=============================================" -ForegroundColor Cyan
Write-Host " Defender for Endpoint Device Risk Report" -ForegroundColor Cyan
Write-Host "=============================================" -ForegroundColor Cyan
# Get an app-only token for the WindowsDefenderATP API (separate from Graph)
$plainSecret = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($ClientSecret))
$body = @{
grant_type = "client_credentials"
client_id = $ClientId
client_secret = $plainSecret
resource = "https://api.securitycenter.microsoft.com"
}
$token = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$TenantId/oauth2/token" -Body $body
$headers = @{ Authorization = "Bearer $($token.access_token)" }
try {
$machines = Invoke-RestMethod -Method Get -Uri "https://api.securitycenter.microsoft.com/api/machines" -Headers $headers
} catch {
Write-Error "[ERROR] Failed to query Defender for Endpoint machines: $_"
exit 1
}
$report = $machines.value | Select-Object computerDnsName, osPlatform, healthStatus, riskScore, exposureLevel, lastSeen
$report | Export-Csv -Path $OutputPath -NoTypeInformation
$atRisk = $report | Where-Object { $_.riskScore -in @("Medium", "High") }
Write-Host "[SUCCESS] $($report.Count) device(s) written to: $OutputPath" -ForegroundColor Green
if ($atRisk) {
Write-Host "[WARNING] $($atRisk.Count) device(s) at Medium risk or above:" -ForegroundColor Red
$atRisk | Format-Table computerDnsName, riskScore, exposureLevel -AutoSize
} else {
Write-Host "[INFO] No devices currently above Low risk." -ForegroundColor Green
}Read it before you run it, and test in a safe tenant first.