🎁 New User? Get 20% off your first purchase with code NEWUSER20 Register Now →
Menu

Categories

Intune Device Management with Microsoft Graph API: Compliance, Configuration, Wipe (2026)

Intune Device Management with Microsoft Graph API: Compliance, Configuration, Wipe (2026)
Intune Microsoft Graph API guide

Intune sits on top of Microsoft Graph — every action you take in the Intune admin center is a Graph API call. That is good news: anything you can do in the portal you can script. Inventory all 5,000 devices, find which ones are non-compliant, push a configuration profile to a group, remote-wipe a stolen laptop — all from PowerShell, all auditable.

This guide covers the most common Intune operations, the scopes they need, and the patterns to get them right. Free PDF cheat sheet at the bottom.

Required scopes

  • DeviceManagementManagedDevices.Read.All — read inventory
  • DeviceManagementManagedDevices.PrivilegedOperations.All — wipe / retire / fresh start
  • DeviceManagementConfiguration.Read.All — read configuration profiles
  • DeviceManagementConfiguration.ReadWrite.All — create / modify profiles
  • DeviceManagementApps.Read.All — read app inventory

Device inventory

Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All"

# All devices
$devices = Get-MgDeviceManagementManagedDevice -All
$devices.Count   # 4,832

# Pull useful columns
$devices | Select-Object DeviceName, OperatingSystem, OsVersion,
    Manufacturer, Model, ComplianceState, LastSyncDateTime,
    UserPrincipalName |
    Sort-Object LastSyncDateTime -Descending |
    Select-Object -First 20

Compliance status

# Compliance state distribution
$devices | Group-Object ComplianceState |
    Format-Table Name, Count -AutoSize

# Non-compliant Windows devices
$badWin = $devices | Where-Object {
    $_.OperatingSystem -eq 'Windows' -and $_.ComplianceState -ne 'compliant'
}

# Per-policy compliance (most useful)
$badWin | ForEach-Object {
    $states = Get-MgDeviceManagementManagedDeviceCompliancePolicyState `
        -ManagedDeviceId $_.Id |
        Where-Object State -ne 'compliant'
    [PSCustomObject]@{
        Device   = $_.DeviceName
        UPN      = $_.UserPrincipalName
        Policies = ($states | ForEach-Object { $_.DisplayName }) -join '; '
    }
} | Export-Csv .\noncompliant.csv -NoTypeInformation

Filter by OS, model, last sync

# Devices not synced in 30 days
$stale = $devices | Where-Object {
    $_.LastSyncDateTime -lt (Get-Date).AddDays(-30)
}

# By model
$devices | Where-Object Model -like 'Surface*' |
    Group-Object Model | Format-Table Name, Count

# Server-side filter for huge tenants
Get-MgDeviceManagementManagedDevice -All `
    -Filter "operatingSystem eq 'iOS' and lastSyncDateTime lt 2025-01-01T00:00:00Z"

Configuration profiles

# List all device configuration profiles
Get-MgDeviceManagementDeviceConfiguration -All |
    Select-Object DisplayName, Id,
        @{n='Type';e={$_.AdditionalProperties.'@odata.type' -replace '#microsoft.graph.',''}}

# Get one profile in full
$p = Get-MgDeviceManagementDeviceConfiguration -DeviceConfigurationId $profileId
$p | ConvertTo-Json -Depth 10

Creating profiles via Graph is supported but the JSON body is large and very specific to the profile type. For most teams, manage profiles in the portal and script the assignment instead.

Assign profiles to groups

$profileId = ""
$groupId   = (Get-MgGroup -Filter "displayName eq 'Pilot-Group'").Id

$body = @{
    assignments = @(
        @{
            target = @{
                "@odata.type" = "#microsoft.graph.groupAssignmentTarget"
                groupId       = $groupId
            }
        }
    )
}

Invoke-MgGraphRequest -Method POST `
    -Uri "/v1.0/deviceManagement/deviceConfigurations/$profileId/assign" `
    -Body $body

Remote actions: sync, wipe, retire, restart

# Force a check-in (sync) - low-risk, useful after policy change
Invoke-MgGraphRequest -Method POST `
    -Uri "/v1.0/deviceManagement/managedDevices/$deviceId/syncDevice"

# Restart Windows device
Invoke-MgGraphRequest -Method POST `
    -Uri "/v1.0/deviceManagement/managedDevices/$deviceId/rebootNow"

# Wipe (factory reset, KEEP enrollment)
Invoke-MgGraphRequest -Method POST `
    -Uri "/v1.0/deviceManagement/managedDevices/$deviceId/wipe" `
    -Body @{ keepEnrollmentData = $true; keepUserData = $false }

# Retire (remove company data, leave personal data alone)
Invoke-MgGraphRequest -Method POST `
    -Uri "/v1.0/deviceManagement/managedDevices/$deviceId/retire"

# Delete the device record (after retire)
Remove-MgDeviceManagementManagedDevice -ManagedDeviceId $deviceId

For a stolen device, the right sequence is: retire (wipe corporate data immediately), then wipe when the device next checks in (full factory reset). Privileged operations require the explicit privileged scope.

Managed app inventory

# All apps deployed via Intune
Get-MgDeviceAppManagementMobileApp -All |
    Select-Object DisplayName, Publisher, CreatedDateTime,
        @{n='Type';e={$_.AdditionalProperties.'@odata.type' -replace '#microsoft.graph.',''}}

# Apps installed on a specific device
Get-MgDeviceManagementManagedDeviceDetectedApp -ManagedDeviceId $deviceId

Cheat sheet

The full reference on a single PDF: Intune Graph API Cheat Sheet.

FAQ

Where do I find the device ID?

Get-MgDeviceManagementManagedDevice -Filter "deviceName eq 'LAPTOP-X1'" or via the Intune admin center on the device's overview page.

Why does compliance show "unknown"?

Either the device has not checked in since enrollment (no compliance evaluation has run), or there is no compliance policy assigned to the user/device. Trigger a sync via the Graph API and re-check after 5 minutes.

Can I bulk-wipe a list of devices?

Yes — loop through the IDs and call the wipe endpoint for each. Add a small Start-Sleep between calls to avoid throttling. Always test on one device first.

What is the difference between wipe and retire?

Wipe = factory reset (everything gone). Retire = remove only company-managed apps and data (personal data on BYOD devices stays). Pick retire for off-boarded employees on personal devices, wipe for lost or stolen.

Can I create configuration profiles through Graph?

Yes — but the JSON body is profile-type specific and verbose. Most teams find it more practical to author profiles in the portal and use Graph for assignment, reporting, and bulk operations.

How do I avoid throttling for tenant-wide reports?

Use -All with the SDK (it handles paging and back-off), $select to limit returned columns, and process the result in memory rather than re-querying per device.

Are remote actions logged?

Yes — every action shows in the Intune admin center under the device's "Activity" tab and in Azure Monitor logs if you stream Intune audit data there.

Related reading

Share this article:
Dargslan Editorial Team (Dargslan)
About the Author

Dargslan Editorial Team (Dargslan)

Collective of Software Developers, System Administrators, DevOps Engineers, and IT Authors

Dargslan is an independent technology publishing collective formed by experienced software developers, system administrators, and IT specialists.

The Dargslan editorial team works collaboratively to create practical, hands-on technology books focused on real-world use cases. Each publication is developed, reviewed, and...

Programming Languages Linux Administration Web Development Cybersecurity Networking

Stay Updated

Subscribe to our newsletter for the latest tutorials, tips, and exclusive offers.