Microsoft Intune¶
Intune is Microsoft's device and app management service. Through the Graph API you can inventory devices, push configuration and compliance policy, protect app data, run remote actions, and audit everything an administrator does. This folder is a guided tour: start with the lifecycle, then open the stage you care about.
This is not "yet another API list". Every script runs against a real tenant, explains what it does and why you would use it, and — when a permission has not been consented or the tenant has no data — prints the missing scope and exits
0instead of failing.
How Intune works — the lifecycle¶
Intune is easiest to reason about as a pipeline. A device moves through these stages, and each stage has its own folder here:
flowchart LR
A["1. Enrol\nWho may join, and how"] --> B["2. Register\nDevice shows up"]
B --> C["3. Configure\nProfiles & compliance"]
C --> D["4. Protect\nApps & data (MAM)"]
D --> E["5. Manage\nRemote actions"]
E --> F["6. Govern\nCompliance & reports"]
F --> G["7. Audit\nWho changed what"]
G -. "administer: roles, categories, templates" .-> A
| Stage | Question it answers | Folder |
|---|---|---|
| 1. Enrol | Who and what may enrol, and how? | enrollment/ |
| 2. Register | Which devices does Intune now manage? | devices/ |
| 3. Configure | What settings and compliance rules apply? Who do they reach? | policies/ |
| 4. Protect | Which apps may access corporate data? | apps/ |
| 5. Manage | What can I do to a device right now? | devices/ |
| 6. Govern | Is the fleet healthy? Why did enrolment fail? | reports/ |
| 7. Audit | Who changed what, and when? | audit/ |
| Administer | Who is allowed to do all of the above? | administration/ |
The object model¶
Everything hangs off two singletons on the client. Knowing which one to use is half the battle:
flowchart TD
C["GraphClient"] --> DM["client.device_management\ndevices, policies, reports, audit, RBAC"]
C --> DAM["client.device_app_management\napps, MAM policies, VPP tokens"]
DM --> D["managed_devices"]
DM --> P["device_compliance_policies"]
DM --> CF["device_configurations"]
DM --> R["reports → export_jobs, activity"]
DM --> A["audit_events"]
DAM --> APP["mobile_apps"]
DAM --> MAM["managed_app_policies"]
DAM --> VPP["vpp_tokens"]
There is no top-level client.intune; device_management is the Intune
namespace, and app-facing resources live under device_app_management.
Start here¶
| # | Script | What you get |
|---|---|---|
| 0 | quickstart.py |
Connect, count devices, read the enrolment overview |
| 1 | lifecycle.py |
Walk all seven stages against your tenant in one run |
Authentication — read this first¶
Intune needs an Intune role as well as a Graph permission, and there is a real difference between auth modes:
- Application (client secret / certificate) — what a background service
should use, but the app registration must be granted the
DeviceManagement*application roles and an Intune admin must assign it a role. On the demo tenant used to build these examples the app-only token has no Intune roles, so every call is403. - Delegated (username + password / interactive) — signs in as a person. It is the only mode that works out of the box on the demo tenant, so the examples use delegated ROPC:
from office365.graph_client import GraphClient
client = GraphClient(tenant=tenant).with_username_and_password(client_id, username, password)
Use with_client_secret(...) / with_certificate(...) in production and
grant the corresponding application permissions; the resource paths in
every script are identical.
| Permission | Lets you read/write | Used by |
|---|---|---|
DeviceManagementManagedDevices.Read.All |
Devices, overview, detected apps | quickstart, devices/, lifecycle |
DeviceManagementManagedDevices.ReadWrite.All |
Above + update device properties | devices/primary_user |
DeviceManagementManagedDevices.PrivilegedOperations.All |
Remote actions, primary user changes | devices/remote_actions, devices/primary_user |
DeviceManagementConfiguration.Read.All |
Compliance policies, configuration profiles | policies/, devices/compliance |
DeviceManagementApps.Read.All |
Mobile apps, MAM policies, VPP tokens, audit events | apps/, audit/ |
DeviceManagementServiceConfig.Read.All |
Enrolment config, Autopilot, categories, templates | enrollment/, administration/, protection/ |
DeviceManagementRBAC.Read.All |
Role definitions and assignments | administration/roles.py |
Admin consent is required. The Graph permissions reference lists the application/delegated split for each.
A note on an empty (or restricted) tenant¶
The demo tenant has zero managed devices and only a subset of the Intune scopes consented. The examples are written for that reality:
- lists render
(0)or "No managed devices matched" — not an error; - a
403prints[skipped] <code>: <the exact missing scope>and exits0; reports/export_jobs.pypolls a genuine long-running operation and reports "still running" cleanly when it hits the--timeout.
If you want data to look at, enrol one device (or run the examples against a production tenant) and they light up without any change.
Running the examples¶
# from the repository root, with the project's virtualenv
.venv/bin/python examples/intune/quickstart.py
.venv/bin/python examples/intune/devices/inventory.py --compliance noncompliant
.venv/bin/python examples/intune/reports/export_jobs.py --report Devices
Credentials come from tests/settings (client_id, tenant, username,
password). Anything that writes a file writes to the system temp directory
unless you pass an explicit path, so nothing is left in the repository.