Reports¶
The govern stage: turning raw state into answers. Intune exposes reports as
Graph report functions on client.reports, plus export jobs for reports
too large to return inline.
flowchart LR
A["client.reports\ndevice_activity / enrollment"] --> R["Report.content\n(raw payload)"]
J["reports.export_jobs.add(...)"] --> P["poll by id\nnotStarted → inProgress → completed"]
P --> U["download URL → file"]
Start here¶
| Script | What / why | Permissions |
|---|---|---|
device_activity.py |
Device-configuration user/device activity. The report body can legitimately be empty; the script prints its size. | DeviceManagementConfiguration.Read.All |
enrollment_failures.py |
Why enrolment failed (failureDetails) and the topFailures ranking, optionally scoped by --period D30. |
DeviceManagementManagedDevices.Read.All |
export_jobs.py |
The long-running case. Create an export job, poll it, download the result. | DeviceManagementManagedDevices.Read.All |
The long-running export flow¶
export_jobs.py is the reference for an Intune LRO:
- Create the job — Graph returns immediately with
status = notStarted. - Poll
reports.export_jobs[<job-id>].get()untilstatus = completed(orfailed). Note: listingexport_jobsis not supported; always poll by id. - Download the pre-signed
urlthe completed job exposes.
Because the job runs server-side, the script is bounded by --timeout and exits
cleanly if the report is still being generated:
The status is normalised case-insensitively, because Graph returns it as the
raw member name (inProgress).