microsoft graph api
6 TopicsFrom hours to minutes: Rethinking Microsoft Intune compliance reporting with the Export API
By: Daniel Gerrity – Principal Product Manager | Microsoft Intune If you manage a large device fleet with Microsoft Intune, you’ve almost certainly needed to get reporting data out of the service at scale — compliance state, device inventory, app status, endpoint analytics, or one of the many other reports admins rely on for operations and audit evidence. Intune supports this pattern through the export API, which generates supported reports as asynchronous export jobs instead of requiring you to retrieve the same data through thousands of operational Graph calls. You can see the full list of reports available through the export API in Intune reports and properties available using Graph API documentation. In the illustrative scenario below, moving one nightly job from operational Graph reporting endpoints to the Intune export API (exportJobs) cuts the work from roughly 100,000 API calls to about 15 while producing the same report data. The runtime drops from ~2.5 hours to ~15 minutes. Here’s how, and why the pattern holds up as your fleet grows. Note on the numbers The figures below are a representative example for a hypothetical 50,000-device enterprise, “Contoso,” and are rounded for clarity. Your results may vary based on fleet size, policy count, and how many compliance settings you evaluate. The scenario Contoso runs a nightly job that answers a deceptively simple question: For each device, across every compliance policy assigned to it, what is the state of each individual setting? This is a classic per-device, per-compliance-policy, per-setting state export. It’s the raw material behind compliance dashboards, audit evidence, remediation targeting, and “why is this device noncompliant” investigations. In Intune’s reporting catalog, this is the DeviceStatusSummaryByCompliancePolicySettingsReportV3 report. Contoso has ~50,000 managed devices, and the job runs once a day. The old way: Operational Graph APIs The intuitive approach treats compliance data as something you fetch, per device, right now. The script: Enumerates the fleet (managedDevices). Loops over every device, and for each one calls the operational reporting or setting-state endpoints (such as managedDevices detail and settingStates) to pull that device’s per-policy, per-setting results. Pages through the results in small JSON pages (often 50 rows at a time), reassembling everything client-side. It works. It just doesn’t scale because the number of calls is a function of the number of devices. At roughly two operational calls per device, 50,000 devices is on the order of ~100,000 Graph calls per run. That volume brings its own tax: Throttling. You hit service protection limits and have to implement retry/back-off logic. Threading. To finish inside the window at all, you parallelize which means concurrency bugs, partial failures, and harder debugging. Fragility. A run that makes 100,000 calls has 100,000 chances to fail, and a mid-run failure often means starting over. Time. End=to-end, the job lands around ~2.5 hours. Every time Contoso onboards more devices, this job gets slower and more expensive - the worst possible scaling direction for something that runs every night. The new way: Export API (exportJobs) The export API flips the model. Instead of asking Graph to compute results device-by-device in real time, you ask Intune to generate the entire report once, server-side, and hand you back a single file. The flow is a short, asynchronous handshake: 1. POST /deviceManagement/reports/exportJobs { "reportName": "DeviceStatusSummaryByCompliancePolicySettingsReportV3", "format": "csv", ...optional filter/select... } → returns a jobId, status: "notStarted" 2. GET /deviceManagement/reports/exportJobs('{jobId}') → poll until status: "completed" (a handful of polls while it builds) → response includes a short-lived download URL 3. GET {download URL} → one zipped CSV containing every device × policy × setting row That’s the whole pattern: request → poll → download → unzip → load. One report, one file, the entire fleet inside it. Count the calls: one POST to start the job, a handful of GET polls while Intune builds the file, and one GET to download it - call it ~15 calls total. Not ~15 per device. ~15 for the whole 50,000-device run. And that number barely moves whether Contoso has 50,000 devices or 150,000. Runtime drops to about ~15 minutes, most of which is simply waiting for the export to finish - cheap poll calls, not active compute. Most importantly, the output schema is identical. The CSV columns match what the old per-device loop assembled, so nothing downstream; dashboards, warehouse tables, alerting, has to change. You swap the acquisition layer and leave everything else alone. Side by side Comparison Operational Graph APIs Recommended Export API ( exportJobs ) Pattern Per-device loop plus paging Async export → download one file API calls per run ~100,000 ~15 Calls scale with Number of devices Nothing. The handshake remains fixed. Runtime ~2.5 hours ~15 minutes Concurrency Threading required None needed Output schema — Unchanged and drop-in compatible Net result — ~6,000× fewer API calls ~10× faster runtime Why it scales: Roundtrips, not bytes Here’s the subtlety worth internalizing, because it’s easy to get wrong. There are two different costs in this job, and they scale on different axes: The number of API calls - round-trips across the wire. The volume of data - the actual compliance rows you move. The data volume is the same either way. 50,000 devices × N settings is 50,000 × N rows, whether you assemble them from 100,000 little paged responses or receive them in one CSV. The export doesn’t move less data - it moves the same data. And yes, that file grows with both device count and setting count. More devices, bigger file; more settings, bigger file. So the win isn’t fewer bytes. The win is fewer round-trips. Every one of those 100,000 operational calls relies on authentication, TLS setup, network latency, and service-protection (throttling) accounting regardless of how much data it returns. Multiply that fixed overhead by 100,000 and it dominates everything. The export only pays that tax twice: once to start the job, once to download the file. Intune does the assembly server-side and streams you the result in a single bulk transfer. That reframes the scaling story: Call count is essentially constant - it doesn’t grow with devices or settings. It’s one job and one download. Data volume grows with devices and settings but a bigger CSV is a bigger single download, not more calls. Bulk transfer is exactly what HTTP is good at. Runtime has a mild data dependency: a larger fleet takes Intune a little longer to build the file. But you absorb that as a few extra seconds of poll-waiting, not as thousands of extra calls you have to orchestrate, retry, and throttle-manage. What the IT admin actually gets Beyond the raw speed, here’s the value that shows up in day-to-day operations: Your maintenance window comes back. A 15-minute job leaves room for everything else. Fewer moving parts to maintain. No custom throttling handler, no thread pool, no resumability logic. Less code is less to break at 2 a.m. Reliability by design. Two roundtrips means two failure points, and the server does the heavy lifting of assembling a consistent snapshot. Lower cost and lower service impact. Eliminating ~100,000 calls is easier on your tenant’s throttling limits and a better citizen for the Intune service overall. Room to grow. Because call count is decoupled from device count, doubling the fleet doesn’t double the job, you just download a somewhat larger file. No downstream disruption. Same schema for the output means the migration is contained to the ingestion step which is a low-risk swap, not a re-platforming. When to use which The export API isn’t a universal replacement, it’s best used for bulk, point-in-time snapshots: Reach for exportJobs when you need the whole fleet’s state (or a large, filtered slice) on a schedule such as nightly compliance loads, audit exports, warehouse hydration. Stick with the operational endpoints when you need a single device right now, an interactive “check this one device” lookup, or a real-time remediation trigger where waiting on an async job doesn’t make sense. The two are complementary. The mistake isn’t using the operational APIs, it’s using them in a loop to reconstruct something the export API will hand you in one file. The takeaway The per-device loop feels natural because it mirrors how we think about devices, one at a time. But at fleet scale, the question isn’t “what’s the state of this device?” a hundred thousand times over. It’s “give me the state of everything,” once. The export API is built for exactly that question, and answering it the right way turned a multi-hour nightly grind into a coffee break - from ~100,000 calls to about 15, ~10× faster, with zero downstream changes. If you have any questions, leave a comment below or reach out to us on X: @IntuneSuppTeam!482Views0likes0CommentsExporting all Microsoft Intune Enterprise App Management catalog apps to CSV using Microsoft Graph
By: Joe Lurie, Sr. Product Manager | Microsoft Intune Managing applications at scale is one of the biggest time-consuming tasks for IT admins. Between packaging installers, writing detection rules, and keeping everything up to date - it adds up fast. That's exactly the problem Enterprise App Management in Microsoft Intune is designed to address. Enterprise App Management gives you access to a curated Enterprise App Catalog with hundreds of popular Win32 apps that are pre-packaged, pre-tested, and ready to deploy. Microsoft handles the install commands, detection logic, and update-ready packaging. Automatic updates for catalog apps are expected to roll out in mid-2026, making the experience even more hands-off. You just pick the app, assign it, and move on. But what if you want a full inventory of what's available in the catalog? Maybe you're evaluating which apps your organization can migrate from manual packaging, or you want to share the list with your app owners for review. In this post, I'll show you how to pull the complete catalog using Microsoft Graph PowerShell and export it to a CSV file. Prerequisites Before you start, make sure you have: Intune admin permissions: An account with Intune permissions to read app and catalog data (such as Intune Administrator or a custom role with app read access). You will also need Microsoft Graph delegated scope: DeviceManagementApps.Read.All (you'll consent to this when connecting). An Intune Suite or Enterprise App Management add-on license: Enterprise App Management is part of the Intune Suite or available as a standalone add-on. Note: Microsoft has announced that Enterprise App Management will also be included in Microsoft 365 E5 licensing starting July 1, 2026 - check current licensing guidance to confirm availability for your tenant. Microsoft Graph PowerShell SDK (Beta module) installed: Note that the catalog API is currently in the beta endpoint which means cmdlet names and properties may change before reaching v1.0. If you don't have the beta module installed yet, run: Install-Module Microsoft.Graph.Beta.Devices.CorporateManagement -Scope CurrentUser -Force Step 1: Connect to Microsoft Graph First, authenticate to Microsoft Graph with the required scope: Connect-MgGraph -Scopes "DeviceManagementApps.Read.All" You'll get a browser prompt to sign in and consent. Once connected, you're ready to query the catalog. Step 2: Retrieve all Catalog apps Microsoft Graph exposes the Enterprise App Catalog through the /beta/deviceAppManagement/mobileAppCatalogPackages collection. The PowerShell cmdlet for it is: $catalogApps = Get-MgBetaDeviceAppManagementMobileAppCatalogPackage -All The -All parameter is important as it handles pagination automatically so you get every catalog package, not just the first page of results. 💡 Tip To see every property available on a catalog package object, pipe the first result to Format-List . $catalogApps | Select-Object -First 1 | Format-List * Step 3: Export to CSV Next, let's select the most useful fields and write them to a CSV file: $csvPath = "C:\Temp\IntuneCatalogApps.csv" New-Item -ItemType Directory -Path (Split-Path $csvPath) -Force | Out-Null $catalogApps | Select-Object ProductDisplayName, VersionDisplayName, PublisherDisplayName | Export-Csv -Path $csvPath -NoTypeInformation Open the CSV in Excel and you've got a clean, sortable list of every catalog package in the Intune Enterprise App Catalog. Putting it all together Here's the complete script you can save and run: # Connect to Microsoft Graph Connect-MgGraph -Scopes "DeviceManagementApps.Read.All" # Pull all Enterprise App Catalog packages $catalogApps = Get-MgBetaDeviceAppManagementMobileAppCatalogPackage -All # Export to CSV $csvPath = "C:\Temp\IntuneCatalogApps.csv" New-Item -ItemType Directory -Path (Split-Path $csvPath) -Force | Out-Null $catalogApps | Select-Object ProductDisplayName, VersionDisplayName, PublisherDisplayName | Export-Csv -Path $csvPath -NoTypeInformation Write-Host "Exported $($catalogApps.Count) catalog apps to $csvPath" -ForegroundColor Green # Disconnect when done Disconnect-MgGraph Sample output Your CSV will look something like this: Product Version Publisher Mozilla Firefox 137.0.1 Mozilla Corporation Google Chrome 135.0.6998.89 Google LLC Zoom Workplace 6.4.6 Zoom Video Communications, Inc. Adobe Acrobat Reader DC 25.001.20467 Adobe Inc. 7-Zip 24.09 Igor Pavlov Why this matters Having a complete list of what's in the catalog is useful for a few scenarios: App rationalization - Share the list with app owners and identify which apps you can stop manually packaging and switch to the catalog instead. Gap analysis - Compare the catalog against your current app portfolio to see what's missing. Change management - Track what's available over time as Microsoft continues to add new apps. Compliance and auditing - Document which catalog apps are available for your tenant. Wrapping up Enterprise App Management is one of the most impactful features in the Intune Suite. It takes the most tedious parts of endpoint management - app packaging and updates - and just handles it for you. And with a short Graph script, you can get full visibility into what's available. And to see how Enterprise App Management secures your app catalog, check out the companion post here: aka.ms/Intune/EAM-Security. Give the script a try and let us know what you think along with other Enterprise App Management topics you’d like to see by leaving a comment below or reaching out on X @IntuneSuppTeam. Want to learn more about Enterprise App Management? Check out the official documentation for the full details. Join our community! Discuss real-world scenarios, get expert guidance, connect with peers, and influence the future of Microsoft Security products. Learn more at https://aka.ms/JoinIntuneCommunity.2KViews0likes1Comment