You’re Missing Critical M365 Compliance Data – Here’s Why
24 Minuten
Podcast
Podcaster
M365 Show brings you expert insights, news, and strategies across Power Platform, Azure, Security, Data, and Collaboration in the Microsoft ecosystem.
Beschreibung
vor 4 Monaten
If your compliance dashboards always seem a step behind, you’re
not alone. Most standard tools skip over entire categories of
critical risk, and manual reporting eats up hours only to deliver
incomplete results.Today, you’ll see exactly which Microsoft
Graph APIs hold your compliance blindspots and how to plug those
gaps using scripts and Purview—no guesswork, just real answers
that turn compliance chaos into clarity.
Why Your Compliance Reports Miss the Big Picture
Let’s start with that nagging feeling you get after a compliance
audit: You’re staring at spreadsheets, exports, or the default
Microsoft 365 dashboards, but something always seems off. No
matter how many times you hit “Export CSV” or download a fresh
report, the confidence just isn’t there. You review the numbers,
scroll through pages of rows, and maybe you even try
cross-referencing the data with incident notifications or emails
from your security team. The frustration settles in quickly. Why
does it always seem like there’s something missing, even when
you’ve done everything the official guidance recommends?The
answer usually sits in how the majority of teams treat Microsoft
365 compliance reporting as a box to check. Built-in dashboards,
Security & Compliance Center exports, audit log
downloads—they’re all simple, accessible, and they look official
enough to pass a glance in an annual review. For a lot of admins,
running those out-of-the-box reports feels like covering your
bases. If there are checkboxes, percentage bars, or even a few
green lines, it’s easy to assume you’ve captured the most
important risks. But real-world incidents have a habit of
slipping past these reports, unnoticed until they explode into
actual problems.Consider a review scenario that plays out more
often than anyone wants to admit. An external auditor sits down
and asks for evidence of DLP incidents handled in the last
quarter. You share your compliance exports—after all, that’s what
Microsoft recommends in the UI. The auditor, though, is scanning
for a very specific case that the legal team flagged months ago.
You check again, but it’s nowhere. After some back-and-forth, you
realize there was an eDiscovery case that the compliance portal
never even listed, because it lived outside the normal workflow.
The incident, documented in emails and maybe even in a few Teams
chats, didn’t make its way into the standard report. Now you’re
left scrambling, patching together fragmented evidence and hoping
there’s no follow-up question you can’t answer.It’s not just a
fluke. Microsoft’s documentation makes a point of reminding
admins that standard dashboards provide summary overviews, but
advanced or “hidden” details only show up if you tap into
specific, less obvious data sources. There are a handful of blunt
hints in the docs: “Certain compliance actions may not appear in
standard audit logs” or “To access advanced eDiscovery
activities, use Graph or PowerShell endpoints.” It’s like running
an antivirus scan you assume checks everything, only to learn it
skipped an entire disk partition without telling you. The users
feel safe, but the threat’s still lurking, just out of sight.When
you stack these gaps across multiple teams and multiple review
cycles, you start to see just how much risk goes undetected. The
Compliance Center UI, for example, doesn’t always reflect the
full scope of DLP policies and can lag behind on status from
ongoing eDiscovery cases. And when something gets flagged outside
the usual channels—maybe by a third-party tool or a direct alert
from Graph APIs—it rarely gets retroactively added to your last
quarterly report. Here’s where the illusion of coverage bites
back: More than 60% of compliance personnel admitted, in a 2023
study, they lean almost exclusively on standard Microsoft 365
dashboards and exports for their compliance evidence packages.
That means the majority are working with incomplete or stale
data, missing everything from shadow eDiscovery cases to the
quiet DLP hits that don’t generate visible alerts.It’s not just
an admin problem, either. Legal, HR, and risk teams all build
business, disciplinary, or investigational decisions off these
Microsoft-recommended views. When these professionals run their
own checks—imagine a legal hold that never shows up in the UI, or
an HR inquiry into information leakage that comes up
blank—they’re getting only a slice of what’s happening in their
tenant. Every scenario like this chips away at trust in
compliance data, leading to more manual reviews, longer audits,
and way more room for error.So, why are these blind spots so hard
to actually see? It comes down to how Microsoft structures its
reporting endpoints. Standard compliance exports are based on
high-level, aggregated tables designed to be quick and
consumable. The deep-dive data—the good stuff with granular
eDiscovery history, underlying alert metadata, and the full
run-down of DLP policy matches—lives in separate endpoints
accessed through Microsoft Graph. Most admins never touch these
endpoints, either because they’re not aware they exist or they
assume it’s only something developers would need. But these Graph
APIs are where the most actionable compliance data is hidden.
They aren’t front-and-center in the interface, the permissions
are confusing, and even seasoned IT pros can go years without
realizing there’s a whole other universe of data just outside
their reach.The reality is, if you’re only looking at the
built-in compliance dashboards, you’re running with partial
visibility. All the exports in the world can’t save you from
invisible risks if you don’t know where to look. So, let’s get
right to it: There are Graph API endpoints that surface all those
missing incidents, policies, and cases—and you can start
unlocking them without risking your tenant or breaking your
reporting workflows. This isn’t theory, and it isn’t just for
coders. Anyone who’s worked with compliance data knows how much
easier life gets once you stop guessing and start pulling the
data that’s actually there. And this is where things start to get
interesting—because next, we’re going to get hands-on with the
endpoints that do all the heavy lifting under the hood, and talk
about how to tap into them, one by one.
Cracking Open Microsoft Graph for Compliance Gold
It’s easy to dismiss the Microsoft Graph API as something only
developers care about. There’s code everywhere, permissions lists
that scroll for miles, and endpoints with names that don’t
exactly roll off the tongue. But here’s the thing: buried in
those REST endpoints is compliance data that never makes it into
your regular dashboards or audit logs. If you skip Graph, you’re
missing whole categories of traceability your organization needs.
Microsoft Graph is more than a developer toyset; it’s the central
nervous system of all your Microsoft 365 data, tying together
everything from Teams messages and Azure AD accounts to
SharePoint file activity. But—and this is what most folks don’t
realize—not every Graph endpoint is created equal when it comes
to compliance. In fact, only a handful of them actually surface
incident-level information that legal or risk teams care about.So
let’s talk about what actually happens when you point your
scripts at Graph. When an admin first opens up Graph Explorer or
fires off a test request in PowerShell, the default instinct is
to try the endpoints that sound familiar. /users, /mail,
/drive—these are where all the demos and documentation start. You
get mailbox activity, sign-in logs, or some SharePoint site
changes. It’s all fairly safe, and most of it looks similar to
what you can already see in the admin center. But that’s where
the compliance coverage starts and ends for most people. If
you’re only poking at these surface-level endpoints, you’re blind
to the places where Microsoft 365 really buries incident
data.Now, say you’re an admin tasked with pulling a quarterly
compliance report. You get your mailbox logs without much
trouble, because the permissions are basic and the docs are
everywhere. But DLP activity? Suddenly you get a string of errors
about missing permissions—or, worse, your query just returns zero
results with no explanation. This exact scenario plays out all
the time. Nobody tells you upfront that incidents like DLP hits
and eDiscovery case activity don’t appear unless you use specific
endpoints, like /security/dataLossPreventionPolicies and
/compliance/ediscovery/cases. Miss these, and you’re left with an
incomplete audit trail that skips over some of the most sensitive
actions happening in your environment.The catch is, Microsoft
intentionally segregates these compliance-heavy endpoints from
the regular core Graph namespace. For anything
sensitivity-related or involving security incidents, you usually
have to authenticate against the Security & Compliance
Center—sometimes with a completely different set of permissions
than what you’d use for user or group queries. It’s not as simple
as just using your global admin account either. Some of these
permissions are so specific that even experienced admins get
tripped up the first time around. That’s led to a cottage
industry of half-baked scripts shared in forums or GitHub repos,
which look useful on the surface but quietly skip the endpoints
where the real compliance gold is stored.What’s interesting is
that until recently, Microsoft’s own reporting APIs were even
less capable than they are now. After several public
incidents—where breaches or data leaks slipped past standard
compliance exports—Microsoft started rolling more compliance
signals into Graph. They didn’t send a press release or put a
sticky banner next to the Azure AD portal. Instead, you have to
dig through release notes or Git commits to notice how, for
example, /security/alerts has quietly grown to cover more alert
types, or how /compliance/ediscovery/cases lets you pull both
open and closed investigations, with detailed event history
attached. These changes matter because they signal that
Microsoft’s thinking has finally shifted. Compliance isn’t just a
reporting layer anymore; it’s now a first-class citizen in the
Graph API ecosystem, if you know where to look.The pitfall is
still lurking, though: picking the wrong endpoint, or botching
the authentication flow for these protected segments. One admin I
talked to last month built an automated script to export mailbox
audit logs—great. But the same script tried hitting DLP and
eDiscovery endpoints with generic user permissions, only to bring
back empty results. Because the Security & Compliance Center
endpoints sit on their own permission island, you end up with
two-thirds of the data and one massive hole where the incidents
should be. The result? Hours lost to debugging, with nothing to
show in the compliance report but blank cells.Let’s put some
clarity on which endpoints are worth your time. For compliance
reporting that actually closes the data loop, the heavy hitters
are /security/alerts, /compliance/ediscovery/cases, and
/security/dataLossPreventionPolicies. Each endpoint taps into a
different risk vector—active threat alerts, legal case activity,
and DLP events. But this isn’t just a matter of plugging in a new
URL. For each of these, you need to pre-authorize the right
permissions, scope the OAuth tokens carefully, and double-check
what each response object gives you. The differences aren’t just
in the field names but in the presence—or absence—of entire
nested entities. That dictates whether your output just shows a
summary or delivers deep detail, like user actions, escalation
steps, or even remediation timestamps. Without this, your
compliance “evidence” is always just a partial story.Getting
through those permission puzzles is worth it, though, because
once you have access, the quality of the output jumps. You’re not
just seeing whether a policy fired; you’re getting who triggered
the event, what files were involved, what remediation steps got
taken, and the chain of actions inside an eDiscovery case. That’s
the granular context auditors chase and business leaders need to
make real decisions.So with all that said, having the right keys
to these Graph endpoints gives you a live window into compliance
risk as it happens, not just historical snapshots. But having
access is only part of the challenge. Next comes the task of
scripting—and actually pulling the events, policies, and cases
that matter, in a way that makes sense for your business and is
defendable in an audit. Let’s walk through what that really looks
like, and what you need to watch for if you want your compliance
reporting to actually deliver.
Scripting Compliance: PowerShell and Python in Action
If you’ve ever fired up PowerShell or Python to script compliance
reporting, you know firsthand it’s not a smooth ride. You’ve
followed the docs, maybe borrowed some sample code, and punched
in your tenant details—only to watch OAuth authentication fail,
or find your output filled with empty arrays when you’re sure
incidents happened that week. It’s that classic scenario where
you know the data is hiding somewhere, but every attempt to
automate ends up making the gaps look bigger, not smaller.On
paper, scripting against Graph seems straightforward. In
practice, Microsoft’s OAuth flow brings a checklist of hurdles:
you need the right application registrations, explicit admin
consent on the right scopes, and a solid grasp of how Graph
expects you to pass tokens. Miss any step, and the API returns
either opaque errors or worse, a successful query with absolutely
zero content. This is the point where you start triple-checking
portal logs and wondering if something’s wrong with your tenant.
Most of the time, the issues boil down to mismatched permissions
or endpoints that require elevated scopes—especially for anything
under /security or /compliance.And then there’s the structure of
the API responses themselves. The Graph documentation lays out
payloads as JSON, but the nested properties and inconsistent
field population can throw off even experienced admins. When
you’re dealing with something like DLP policy matches, the actual
incidents are nested three or four layers deep within the
response. If your script only parses the top level, you’ll never
see who triggered which incident or whether a remediation
workflow was kicked off. That’s why so many DIY scripts floating
around fail to return anything useful for compliance endpoints:
they grab the summary, miss the detail, and leave you reporting
on a set of empty shells.Let’s say someone writes a PowerShell
script that uses the /security/dataLossPreventionPolicies
endpoint. The query works, and they get a list of policy objects.
It looks promising until you realize none of the returned fields
cover the incident status, the user involved, or the kind of
matched content that actually landed you in hot water with the
auditor last quarter. The same goes for eDiscovery case
status—you need to hit both the /compliance/ediscovery/cases and
the nested event endpoints, otherwise major changes like
custodian adds, removals, or escalation events go missing from
your final report. One script does its job, but without the full
set of API calls wired up, you get a piecemeal view of
risk.Another headache is the authentication story. Even for
admins, using delegated permissions rarely cuts it for compliance
endpoints. The majority require application permissions, which
means going through extra hoops with app registrations and admin
consent. And while open-source tools try to fill the gap—there
are modules like MSGraph for PowerShell or Python’s
requests-based scripts—they don’t provide pre-built functions for
DLP events or eDiscovery case management. Most of the example
repos you’ll find stop at exporting user data or mail activity,
and veer away from anything security-sensitive. So every team
ends up building their own fragile wrappers or pasting together
half a dozen scripts just to get through an audit.The biggest
pitfall is treating the Graph query as the finish line. It isn’t
enough to pull “some” JSON and assume the story’s complete. APIs
for compliance only expose what the token and scope allow, and
often omit the child properties if you forget to explicitly
expand them in your query. You need to use $expand clauses, dig
into nested lists, and double-check the actual field names. It’s
brutally easy to run a script, scan the first page of output, and
miss entire clusters of incidents that never loaded because of a
pagination or filter miss. And pagination—don’t get me started.
Anything with serious volume, like multiple DLP incidents in a
busy enterprise, requires looped requests and robust handling of
nextLink pointers. A one-liner often isn’t enough.But here’s the
kicker: If you script it correctly, the heavy lifting doesn’t
take hundreds of lines. With a clear understanding of which
endpoints feed which report sections, you can surface DLP
incidents, case statuses, and security alerts in as little as 15
to 20 lines of Python or PowerShell. Pull the data, parse the
nested results, join with user properties for context, and
suddenly you have a compliance snapshot that goes way beyond what
the portal gives you. This is the difference between telling an
auditor, “here’s what the dashboard says,” and actually proving,
“here’s every action that happened, when, and who was
involved.”One thing to always do before patting yourself on the
back: Take your script’s output and compare it, line by line,
against your standard portal exports. Missing an incident? Check
your scopes. Empty fields? Dive deeper into the JSON.
Discrepancies will tell you which API calls or permission tweaks
you’ve missed. Every false negative in your automation is a
potential risk hiding in plain sight—so that cross-check isn’t
just best practice, it’s ground truth.Once you have scripts
reliably pulling down the incidents, case changes, and DLP events
that usually vanish from standard views, you hit a new wall—how
to get this technical data into a format your compliance, legal,
or business teams actually use. Raw JSON, CSV, or Excel dumps
only take you so far if people can’t interpret them quickly.
That’s where centralizing, tagging, and transforming these raw
results with Microsoft Purview starts to shift the game. Here’s
where all those fragmented scripts finally work together.
Turning Data into Decisions: Centralizing with Purview
If you’ve ever tried to make sense of a folder stuffed with JSON
files from all those automated Graph queries, you know the
headache. Pulling the raw data is already a battle—now, staring
at those exports, the next battle starts: actually turning all
this noise into a compliance report that your CISO or an external
auditor can understand without hours of handholding. There’s no
nice summary, just deeply nested lists, cryptic incident IDs, and
a level of granularity that looks impressive right up until
someone asks, “So, is this everything?” Realistically, security
teams end up dumping these outputs into Excel, writing hasty
formulas, then wrestling with ten-minute Power BI refreshes that
still leave inconsistencies. That’s not compliance insight—it’s
just digital clutter.The thing is, most teams run into the same
bottleneck. Everyone cobbles together two or three scripts—one
for DLP activity, another for eDiscovery cases, maybe a third for
pulling security alerts. It’s the “just get it out fast”
approach. But these exports never line up perfectly. You’re left
with separate CSVs, maybe a half-finished dashboard, and more
manual copy-paste than any modern enterprise should tolerate. The
result? When it’s time for a review, someone has the fun job of
playing air traffic controller, sorting through hundreds of rows,
trying to reconcile case names that were typed slightly
differently, checking timestamps, and inevitably missing context
on at least half the incidents flagged. If even one security
event slips through, the audit trail shreds itself just as the
scrutiny ramps up.Now picture an audit scenario for a global
business. You’ve just built a shiny new set of Graph scripts, but
as soon as an external auditor requests a DLP incident summary,
you realize the data is actually spread out across three CSVs and
an aging Power BI dashboard synced to last month’s data. Each
tool shows a piece of the picture, and neither one lines up
perfectly with the story your risk team needs to tell. Incidents
show up with different labels. User info is missing. If anyone on
the review call starts asking for detailed case activity—say,
“Can you show me who reviewed incident #246 in this
list?”—suddenly it’s a patchwork of manually-stitched exports.
It’s a story that’s missing chapters.Here’s where Microsoft
Purview starts to make sense as more than just another portal.
The usual compliance workflow is a minefield of manual steps, but
with Purview in the middle, you can create a single hub that
receives, tags, and contextualizes everything from your
Graph-powered scripts. At its core, Purview lets you bring
together data sources—API exports, custom script outputs, even
third-party logs—and centralize them under a tagging and labeling
system that your compliance staff can actually use. No more
paste-and-pray in Excel, no more scrolling through raw JSON.
Incidents get tagged by type, mapped to owners, and surfaced in
unified dashboards. For the first time, you can see every case,
alert, or policy breach in one place—alongside real user context
and actions taken.But let’s not pretend the handoff is
plug-and-play. Microsoft markets Purview as “the single pane of
glass for risk and compliance,” but actually wiring up external
script outputs takes more effort than the press materials
suggest. You’ll spend time mapping JSON fields to Purview’s
schema, tweaking import formats, and sometimes working around API
limitations that seem designed by a team that’s never met a
compliance analyst. And yet, if you’ve gotten as far as building
clean outputs from Graph, these extra steps are just the finish
line you need. The real trick is standardizing your scripts’
outputs to match what Purview expects. That means grooming your
CSVs, normalizing field names, and turning cryptic incident logs
into tags and labels that surface in Purview workbooks or
reports.Once you get the hang of it, though, Purview gives you
automation options you simply do not get with isolated reports.
You can create rules that flag specific incident types, push
recurring policy matches to the right reviewers, and even set up
alerts when particular user accounts are flagged repeatedly
across different data sources. Everything is timestamped and
auditable in one place—not just in disparate logs or scattered
spreadsheets. For teams chasing ISO standards, GDPR readiness, or
internal audit requirements, this move from fragmented data to
centralized, tagged reporting is transformational: you’re not
just compiling evidence, you’re building defensible stories about
compliance health.There’s also a practical side—integrating
directly with Purview means you can finally automate exports,
generate PDFs or digest emails on schedule, and track incident
status in near-real time. No one’s locked into the labyrinth of
admin centers and browser tabs. You gather what matters, automate
the reporting cycle, and actually make compliance tracking
proactive instead of reactive. The old chase-and-assemble pattern
that plagued your monthly reviews is gone.The payoff is
straightforward: Your compliance dashboards finally reflect real
risk, not just what the default tools want you to see. Incidents
show up live. Decision makers spot trends before they explode
into full-blown investigations. And if audit day rolls around,
you have a clean, consistent call log, every incident tied to a
case, with full history and resolution details ready to go—not
buried across fragmented outputs. With a single, unified
reporting hub in Purview, you move out of survival mode and give
your business the clarity it actually needs. And with scripts
feeding real incidents into that hub, you’re not just showing
that a tool ran—you’re proving that every critical event was
caught, tagged, and handled. That kind of visibility is what
turns compliance from checkbox exercise into real risk
management. This shift isn’t just about making audits easier—it’s
about knowing your blind spots are closed and your reporting can
keep pace with real-world incidents. So now, if legal, HR, or
business leadership wants to see what’s really happening, the
data finally has answers, not excuses. And that brings us to what
this kind of proactive visibility actually means for your
compliance posture, moving forward.
Conclusion
If you’re tired of compliance reports that leave you guessing,
you’re not stuck with what Microsoft 365 shows out of the box.
Graph and Purview let you uncover what’s missing and actually
back up your compliance work with hard evidence—no more blind
spots, and no more mystery incidents just out of reach. Once you
start scripting your own queries, you stop piecing together
partial views and start telling the whole story. If you’re
looking for more real-world automation tactics for Microsoft 365,
make sure you subscribe. Drop your most frustrating compliance
questions in the comments, and we’ll tackle them in a future
episode.
Get full access to M365 Show - Microsoft 365 Digital Workplace
Daily at m365.show/subscribe
Weitere Episoden
22 Minuten
vor 3 Monaten
22 Minuten
vor 3 Monaten
21 Minuten
vor 3 Monaten
22 Minuten
vor 3 Monaten
22 Minuten
vor 3 Monaten
In Podcasts werben
Kommentare (0)