Microsoft Graph PowerShell SDK for Intune Admins: The Complete Guide · CloudEngineerHub
PowerShell11 min read7 views
Microsoft Graph PowerShell SDK for Intune Admins: The Complete Guide
Connect to Intune with the Microsoft Graph PowerShell SDK: scopes, paging, beta vs v1.0, Invoke-MgGraphRequest, throttling, and production-ready reporting scripts.
C
CloudEngineerHub Team
Published: August 29, 2026· Last Updated: October 23, 2026·11 min read
Microsoft Graph PowerShell SDK for Intune Admins: The Complete Guide
Every action you take in the Microsoft Intune admin center is, behind the scenes, a call to the Microsoft Graph API — and the Microsoft Graph PowerShell SDK is the supported, maintained way to make those same calls from a terminal, a scheduled task, or Azure Automation. If you are still reaching for the long-retired AzureAD and MSOnline modules, this guide is your migration path. We cover installation, authentication with least-privilege scopes, paging at fleet scale, the difference between v1.0 and beta endpoints, and production-quality scripts you can adapt on day one.
Visual Walkthrough
Consent, paging and Retry-After: the difference between a script and a liability.
C
CloudEngineerHub Team
Author
The CloudEngineerHub editorial team — Microsoft endpoint management and cloud engineers writing hands-on guides on Intune, Azure, Entra ID, Autopilot, Defender and PowerShell. Every article is reviewed against current Microsoft documentation.
429 + Retry-After honored — backoff, never hammer.
6
Act + log outcomes
Changes applied, results exported for the runbook.
Graph API Call — Token to Throttle-Safe Script. 1. App registered + consented: Application or delegated permission approved (least privilege). — 2. Token acquired: MSAL fetches access token (cached, refreshed silently). — 3. Call Graph endpoint: HTTPS GET/POST/PATCH with $filter, $select, $top. — 4. Page through results: @odata.nextLink loop for large datasets. — 5. Respect throttling: 429 + Retry-After honored — backoff, never hammer. — 6. Act + log outcomes: Changes applied, results exported for the runbook.
Prerequisites
PowerShell 5.1 or, preferably, PowerShell 7.4 LTS running on Windows, macOS, or Linux.
An account with the right role for the task: Intune Administrator for device management work, Global Reader for read-only reporting. A Global Administrator must grant admin consent for new scopes the first time they are requested.
Network access to login.microsoftonline.com and graph.microsoft.com with TLS 1.2 or later.
Access to the PowerShell Gallery for Install-Module (on Windows PowerShell 5.1 you may need the NuGet provider first).
Optional but strongly recommended: Microsoft Graph Explorer for validating queries before you script them.
How It Works
The Intune admin center, the Company Portal, and Windows Autopilot all sit on top of Microsoft Graph, the REST API for Microsoft 365. Intune resources live under the /deviceManagement root: managedDevices holds device objects, deviceConfigurations and the settings catalog hold profiles, deviceCompliancePolicies hold compliance rules, deviceHealthScripts hold remediation scripts, and endpoint security intents hold Defender and baseline policies.
The Microsoft Graph PowerShell SDK wraps those endpoints in cmdlets named after the API path. Get-MgDeviceManagementManagedDevice is a thin wrapper over GET /deviceManagement/managedDevices. Authentication is either delegated (a user sign-in with OAuth scopes) or application-only (an app registration with a certificate, or a managed identity). Two facts shape your daily work:
v1.0 vs beta. Endpoints in v1.0 are production supported; beta endpoints can change without notice. In SDK v2 the beta API ships as a separate module family (Microsoft.Graph.Beta), so you cannot accidentally mix the two profiles in one session.
OData everywhere. Filters ($filter), projections ($select), and paging ($top plus @odata.nextLink) apply to every call, whether you use a first-class cmdlet or Invoke-MgGraphRequest.
Step-by-Step Implementation
1. Install the SDK
Install-Module Microsoft.Graph -Scope CurrentUser installs the full v1.0 module family; add Microsoft.Graph.Beta only when you genuinely need beta endpoints. The SDK imports submodules on demand, so the first call after a fresh session is slow — that is normal, not a hang.
2. Connect with least-privilege scopes
Connect with only the scopes the task needs. Read-only inventory needs DeviceManagementManagedDevices.Read.All; syncing devices or editing assignments needs the ReadWrite variant. Always verify the connection context with Get-MgContext before doing work, and pass -NoWelcome in scripts so the connection banner does not pollute your output.
3. Run your first query
Get-MgDeviceManagementManagedDevice -Top 10 returns one page of device objects. Inspect a single object to learn the property names you will script against: deviceName, operatingSystem, osVersion, lastSyncDateTime, complianceState, userPrincipalName, enrollmentProfileName, and more.
4. Page correctly
Use -All to auto-paginate, or -PageSize 500 to cap per-call payload size. On tenants with thousands of devices, combine -All with a server-side -Filter where the resource supports one, and project with -Property to shrink the response before it crosses the wire.
5. Reach uncovered endpoints with Invoke-MgGraphRequest
Not every Intune endpoint has a first-class cmdlet. Invoke-MgGraphRequest speaks raw REST through your existing connection and handles serialization for you, which makes it the universal escape hatch — including for beta endpoints whose modules you have not installed.
Configuration Deep Dive
Scopes and consent. Connect-MgGraph requests each scope you pass. Once an admin consents, the grant is tenant-wide, but each session still carries only the scopes you requested and every call is evaluated against those scopes plus your Entra role. Least privilege is therefore a two-axis model: Graph scope AND directory role.
Delegated vs application-only. Interactive scripts use delegated permissions and inherit your role. Unattended automation should use an app registration with a certificate, or a managed identity in Azure Automation. Application permissions such as DeviceManagementManagedDevices.ReadWrite.All are tenant-wide by definition, so gate the identity with Conditional Access and store secrets in a vault — never in the script.
Throttling. Graph throttles bursts per caller and per endpoint. On 429 responses, honor the Retry-After header. The SDK retries some throttling internally, but bulk loops that trigger per-device actions should still pause between iterations and fail gracefully on repeated throttling.
Error detail. Graph errors embed the required permission and the failure reason in the response body. Read the whole error, not just the status code — the fix is usually spelled out in the message.
Real-World Enterprise Scenario
A 9,000-device enterprise replaces a brittle scheduled CSV export with a standardized pipeline: one pinned Graph SDK module version from a private repository feed, a service principal holding only DeviceManagementManagedDevices.Read.All, and a single nightly Azure Automation runbook that exports device, compliance, and policy inventory to JSON in a storage account. Finance and CMDB consumers get stable files, auditors get a consistent daily snapshot, and when a new endpoint is needed the team prototypes the query in Graph Explorer, then promotes it into the runbook with Invoke-MgGraphRequest — with zero new permissions granted.
PowerShell for Microsoft Graph Intune Reporting
Script 1 — connect and verify the session:
PowerShell
1
2
3
4
5
6
7
8
9
10
# Connect with the minimum scope needed for device reporting
Connect-MgGraph -Scopes'DeviceManagementManagedDevices.Read.All' -NoWelcome# Confirm which tenant, account, and scopes are actually active
Get-MgContext | Select-Object TenantId, Account, Scopes
# Expected output:# TenantId Account Scopes# -------- ------- ------# 9f2c1e... admin@contoso.com {DeviceManagementManagedDevices.Read.All}
Script 2 — Windows fleet inventory export with paging and projection:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
# Pull ALL managed devices, projecting only the properties we need$devices = Get-MgDeviceManagementManagedDevice -All -Property deviceName,operatingSystem,osVersion,complianceState,lastSyncDateTime,userPrincipalName
# Filter and shape client-side for a clean report$windows = $devices | Where-Object operatingSystem -eq'Windows'$report = $windows | Select-Object deviceName, osVersion, complianceState, lastSyncDateTime, userPrincipalName
$report | Sort-Object deviceName | Export-Csv -NoTypeInformation .\intune-windows-inventory.csv
'Windows devices: ' + $windows.Count + ' of ' + $devices.Count + ' total'# Expected output:# Windows devices: 6104 of 7380 total
Script 3 — tenant policy inventory through raw Graph calls:
Only what the user could do — plus consented scopes.
Application (app-only)
1
Client credentials flow
Secret/cert authenticates the app itself.
2
Application permissions
Wider reach — audit + certificate, never secrets in code.
3
Conditional Access for workload
Workload identities governed too.
4
Rotated + monitored
Cert rotation schedule + sign-in log review.
Graph Permissions — Delegated vs Application. Gate: Who is the actor? — Delegated (user context): User signs in — Delegated (user context): Scope granted — Delegated (user context): Admin consent if needed — Delegated (user context): Least privilege holds — Application (app-only): Client credentials flow — Application (app-only): Application permissions — Application (app-only): Conditional Access for workload — Application (app-only): Rotated + monitored
Common Errors
HTTP 403 "Insufficient privileges to complete the operation." The response body names the missing scope. Reconnect with that scope or have an admin consent for the app registration.
HTTP 400 "Invalid filter clause." Intune resources support a limited set of filterable properties. Use documented filters such as complianceState on managedDevices, or filter client-side with Where-Object.
HTTP 404 on an endpoint you know exists. You are probably hitting v1.0 for a beta-only resource. Point the URI at https://graph.microsoft.com/beta/.
Empty result after a POST. Some actions return HTTP 204 No Content, which is success — check for status rather than a body.
Best Practices
Pin module versions and test SDK upgrades in a lab tenant before production runbooks.
Pass -NoWelcome in scripts and use Get-MgContext assertions before doing work.
Project early with -Property or $select; never ship whole device objects across the wire when you need five fields.
Wrap bulk writes in try/catch, log every failure with the device ID, and continue the loop.
Prototype queries in Graph Explorer, then port the working URL into Invoke-MgGraphRequest.
Prefer PowerShell 7.4 for SDK work — it is faster, cross-platform, and the supported long-term target.
Security Considerations
Managed device data includes user names, compliance state, and encryption status — treat exports as sensitive and store them in protected locations.
Never automate with a Global Administrator. Create a dedicated app registration or automation account with only the scopes it needs.
Prefer certificate credentials or managed identities over client secrets; if you must use secrets, rotate them and keep them in a vault.
Apply Conditional Access to automation identities and review service principal sign-in logs periodically.
Remember that ReadWrite application permissions can retire or wipe every managed device in the tenant — that permission is a crown jewel.
FAQ
Q: Are the AzureAD and MSOnline modules still available?
A: No. They were retired on March 30, 2024. The Microsoft Graph PowerShell SDK is the supported replacement, and Intune management is covered by the Microsoft.Graph.DeviceManagement module family.
Q: How do I query beta-only Intune endpoints?
A: Either install the Microsoft.Graph.Beta module family or, more surgically, call the endpoint with Invoke-MgGraphRequest using a https://graph.microsoft.com/beta/ URI. Keep beta traffic out of production runbooks wherever possible.
Q: How do I find which permission a cmdlet needs?
A: Use Find-MgGraphCommand -Uri /deviceManagement/managedDevices -Method GET, or read the 403 error body, which lists the exact scope required.
Q: Can this run in Azure Automation or GitHub Actions?
A: Yes. In Azure Automation use a managed identity with Connect-MgGraph -Identity; elsewhere use an app registration with a certificate. Both avoid interactive sign-in entirely.
Q: Why does my script work interactively but fail in the scheduler?
A: Scheduled sessions have no cached sign-in. The context is missing scopes or the identity differs — assert Get-MgContext at the top of every script and fail fast with a clear message.
Conclusion
The Graph PowerShell SDK turns the Intune admin center into a programmable surface. Start small — a read-only inventory script with one scope — then grow into bulk actions, assignment audits, and integration with your change process. Master Connect-MgGraph, Get-MgDeviceManagementManagedDevice, and Invoke-MgGraphRequest and you can automate nearly anything the portal can do, faster and more repeatably than clicking ever will be.
Comments
0No comments yet — be the first to share your thoughts.