๐Ÿ›ก Admin session active ยท API Configuration unlocked Sign out
๐Ÿ›ก
Administrator Access
API Configuration ยท Restricted area
Security Overview
Last synced: Connecting...
Total Devices
โ€”
Loading...
Active (7d)
โ€”
Loading...
Inactive
โ€”
Loading...
Patch Compliant
โ€”
Loading...
Defender Updated
โ€”
Loading...
OS Distribution
Device operating systems
Sensor Health
Defender sensor status
โ€”
healthy
Recent Security Events
Last 24 hours from MDE
Live
Asset Inventory
All onboarded devices ยท Microsoft Defender for Endpoint
Device Name Domain OS IP Address Risk Level Onboarded Sensor State
Active / Inactive Assets
Based on last heartbeat ยท 7-day activity window
Active Devices
โ€”
seen within 7 days
Inactive Devices
โ€”
no heartbeat 7+ days
Warning (>3d)
โ€”
approaching inactive
Never Seen
โ€”
onboarded, no check-in
Device Activity Status
All
Active
Inactive
Warning
Device Name Status Last Heartbeat Days Silent OS Assigned User
Compliance Report
Windows Patch status ยท Defender signature version compliance
Windows Patches
Defender Signatures
Overall Score
โ€”
compliant
Per-Device Compliance Detail
Device Name OS Version Pending Patches Defender Ver. Sig. Age Patch Status Defender Status
Last Logon Users
Last interactive logon per device ยท From MDE device record
Device Name Last Logon User UPN Logon Time Days Ago Device Status
API Configuration
Microsoft Defender for Endpoint โ€” Microsoft Graph & MDE API setup
Step 1 โ€” Azure App Registration

Register an Azure AD application to obtain credentials for MDE API access.

  1. Go to portal.azure.com โ†’ Azure Active Directory
  2. App registrations โ†’ New registration
  3. Name: DefenderDashboard
  4. Supported account type: Single tenant
  5. Save the Application (client) ID and Directory (tenant) ID
  6. Certificates & secrets โ†’ New client secret โ†’ copy value
Step 2 โ€” API Permissions Required
WINDOWSDEFENDERATP PERMISSIONS (Application)
Machine.Read.All Machine.ReadWrite.All Alert.Read.All User.Read.All SecurityRecommendation.Read.All Vulnerability.Read.All Software.Read.All
MICROSOFT GRAPH PERMISSIONS (Application)
Device.Read.All DeviceManagementManagedDevices.Read.All AuditLog.Read.All
โš  Admin consent required for all Application permissions
API Endpoints
POST MSAL Browser โ€” Delegated auth (no client secret) Get access token
Why delegated (not client_credentials)?
Browser JavaScript cannot use client_credentials โ€” sending a client secret from the browser exposes it publicly. MSAL's popup flow authenticates the signed-in user and returns a token directly, with no secret needed.
MSAL popup login (used by this dashboard)
// Load MSAL from CDN โ€” no npm needed // <script src="https://cdn.jsdelivr.net/npm/@azure/msal-browser@3/lib/msal-browser.min.js"></script> const app = new msal.PublicClientApplication({ auth: { clientId: 'YOUR_CLIENT_ID', authority: 'https://login.microsoftonline.com/YOUR_TENANT_ID', redirectUri: 'https://your-app.netlify.app', } }); await app.initialize(); const result = await app.loginPopup({ scopes: ['https://api.securitycenter.microsoft.com/machine.read', 'User.Read'] }); const access_token = result.accessToken; // use as Bearer token
GET https://api.securitycenter.microsoft.com/api/machines Asset Inventory
Query parameters
ParamTypeDescription
$filterstringOData filter e.g. osPlatform eq 'Windows10'
$topintMax records to return (default 100, max 10000)
$skipintRecords to skip for pagination
$selectstringSpecific fields to return
Response fields (key)
{ "id": "device-guid", "computerDnsName": "HOSTNAME", "osPlatform": "Windows10", "osVersion": "10.0.19045.3086", "lastIpAddress": "10.0.0.50", "riskScore": "Low", // None|Low|Medium|High "healthStatus": "Active", // Active|Inactive|ImpairedCommunication "onboardingStatus": "Onboarded", "firstSeen": "2024-01-01T00:00:00Z", "lastSeen": "2025-05-22T10:30:00Z" }
Fetch example
const res = await fetch( 'https://api.securitycenter.microsoft.com/api/machines?$top=200', { headers: { Authorization: `Bearer ${access_token}` } } ); const { value: devices } = await res.json();
GET /api/machines?$filter=healthStatus eq 'Active' Active / Inactive Devices
OData filter examples
// Active devices $filter=healthStatus eq 'Active' // Inactive devices $filter=healthStatus eq 'Inactive' // Devices not seen in last 7 days $filter=lastSeen le '2025-05-15T00:00:00Z' // Key field for activity "lastSeen": "2025-05-22T08:14:22Z" // Use to calc days silent "healthStatus": "Active" // Active | Inactive | ImpairedCommunication | NoSensorData
GET /api/machines/{id}/vulnerabilities Windows Patch Compliance
Also useful: software inventory
// Get missing KBs / pending patches GET /api/machines/{deviceId}/vulnerabilities ?$filter=severity eq 'Critical' or severity eq 'High' // Software with known vulnerabilities GET /api/machines/{deviceId}/software // MDE recommendation (patch actions) GET /api/recommendations ?$filter=recommendationCategory eq 'Application' // Response fields { "id": "CVE-2025-00001", "name": "CVE-2025-00001", "severity": "Critical", "publishedOn": "2025-03-01", "updatedOn": "2025-05-01" }
GET /api/machines (avSignatureVersion field) Defender Signature Compliance
Fields from /api/machines response
{ "avEngineVersion": "1.1.24040.5", "avSignatureVersion": "1.409.432.0", "avSignatureUpdateTime": "2025-05-21T14:22:00Z", "avIsSignatureUpToDate": true, // true | false "avIsEngineUpToDate": true, // true | false "defenderAvStatus": "Updated" // Updated | Unknown | NotUpdated | Disabled } // Compliance check โ€” signatures older than 3 days const staleThreshold = 3 * 24 * 60 * 60 * 1000; const isStale = Date.now() - new Date(device.avSignatureUpdateTime) > staleThreshold;
GET /api/machines/{id}/logonusers Last Logon User
Response
GET /api/machines/{deviceId}/logonusers { "value": [ { "id": "domain\\username", "accountName": "jdoe", "accountDomain": "CORP", "logonTypes": ["Interactive"], "firstSeen": "2025-05-20T09:00:00Z", "lastSeen": "2025-05-22T08:14:22Z", // last logon "isDomainAdmin": false, "isOnlyNetworkLogons": false } ] } // Sort by lastSeen descending to get most recent logon user const lastUser = users.sort((a,b) => new Date(b.lastSeen) - new Date(a.lastSeen))[0];
Connect to Live API
Signs in via Microsoft popup โ€” no client secret required
โ‘  Azure App Registration
In Azure Portal โ†’ App registrations โ†’ your app โ†’ Authentication:
Add a Single-page application redirect URI matching your Netlify URL.
e.g. https://your-app.netlify.app
โ‘ก API Permissions
Add Delegated permissions:
WindowsDefenderATP โ†’ Machine.Read.All WindowsDefenderATP โ†’ Alert.Read.All User.Read
Grant admin consent.
TENANT ID
CLIENT ID (App Registration)