Define the report contract
Document the entities, fields, time window, and freshness requirement before writing the request. A report that returns every available property is expensive to operate and difficult to interpret.
Handle Graph as a service
Use least privilege, follow next links, and back off after throttling. Store only the fields needed for the decision. Keep authentication and query logic separate so both can be tested.
$uri = 'https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$select=deviceName,complianceState,lastSyncDateTime'
$rows = @()
do {
$response = Invoke-MgGraphRequest -Method GET -Uri $uri
$rows += $response.value
$uri = $response.'@odata.nextLink'
} while ($uri)Make the output operational
Emit CSV for analysis and a small summary for humans. Include collection time, tenant, query version, and failure counts so a stale report cannot be mistaken for current health.
Operational checklist
- Use a documented field contract.
- Handle pagination and throttling.
- Record collection metadata.
- Keep credentials out of scripts and logs.