How to get a Microsoft Teams presence report
Someone asks you for a "Teams presence report" and the first problem is the phrase means different things to different people. Pin down what the report needs to show before you go looking for a tool, because that decides which option fits.
In practice a presence report answers four questions about a set of people over a window of time: who was available, away, busy, or offline, when each state started, how long it lasted, and (often) how that adds up into online-time totals or trends. A single colored dot in the Teams roster answers none of that. It tells you the state right now and nothing about the past.
So the real question is not "where is the report button," it is "what is going to capture presence over time and turn it into something readable." Here are the honest options.
What the Microsoft 365 reports give you (and where they stop)
The Microsoft 365 admin center has a Teams user activity report, and it is the first place people look. It counts activity: messages sent, meetings attended, calls, and the days each user was active.
What it does not contain is presence status over time. "Active on Tuesday" is not the same as "available at 2pm on Tuesday." If your report needs the available / away / busy / offline timeline, the activity report is the wrong source. It was built to measure adoption, not presence.
That gap is why the other two options exist. Both rely on the same fact: presence has to be captured as it changes and stored, because Microsoft does not keep it for you.
Option A: A PowerShell export against the Graph presence API
Microsoft Graph exposes a presence endpoint, and you can script against it. A scheduled PowerShell job reads presence for a list of users, then appends the results to a CSV or a spreadsheet you can chart later.
This is the right call for a genuine one-off. If you need a single snapshot and never again, do not buy anything. The trade-offs land when the question becomes recurring:
- It only samples when the machine running it is awake. A laptop that sleeps has gaps in the data.
- You own all of it: the storage, the deduplication, the charts, the formatting, and the upkeep when the script breaks.
- There is no access control, retention policy, or audit trail unless you build one.
- It is easy to point at the entire directory by accident, which is exactly the over-collection you usually want to avoid.
We walk through that build-and-maintain reality in the PowerShell vs a tool comparison. The short version: the script is cheap to start and expensive to keep.
Option B: A maintained tool that captures, stores, and visualizes
The category that actually produces an ongoing report is a service that reads the Graph presence API on a schedule, stores each change, and turns the result into timelines and totals you can open and share. The cost moves from your time to a subscription. When you evaluate one, the questions that matter:
- Is it read-only and scoped? It should read presence and the basic directory fields it needs to label people, nothing more. No message content, no files, no screenshots.
- Does it need an agent? A Graph-based tool needs a one-time admin consent and no software on anyone's device.
- What does it retain, and can you delete it? Look for a clear retention window plus per-user and workspace-wide deletion.
- Who can read the report? Role-based access and an audit log matter the moment more than one person has access.
Picking between them
The two real options answer different needs. A quick way to choose:
| Question | PowerShell export | Maintained tool |
|---|---|---|
| One-off snapshot vs ongoing | Fine for one-off | Built for ongoing |
| Who maintains it | You do | The vendor |
| Retention and deletion | You build it | Configured for you |
| Roles and audit trail | You build it | Built in |
| Charts and timelines | You build it | Out of the box |
The deciding factor is usually cadence. If you need the report once, the script wins on cost. The moment it becomes recurring, or more than one person reads it, or a manager should see only their own team, the maintained option wins on everything the table above lists.
How Presify produces this report
Presify is built for exactly this. It reads Teams presence through the Microsoft Graph presence API on a short, regular interval, stores each change, and turns the result into presence timelines, online-time trends, and anomaly flags, per person and per team. The output is exportable, so the report can leave the app as a file when you need to hand it on.
A few things we are deliberate about:
- Read-only and minimal. Presify reads presence plus the basic directory fields it needs to label and scope users. It never touches message content, chats, calls, files, or calendars.
- No agents. Setup is a one-time, read-only Microsoft admin consent. There is nothing to install on anyone's device.
- Tenant-isolated and US-based. Your data is scoped to your Microsoft tenant and processed on US infrastructure.
- Bounded retention you control. History is trimmed automatically by your plan, and per-user and workspace-wide deletion are built in.
Two limits worth stating plainly. Guest users are excluded from monitoring, as are people in the EEA, the UK, Switzerland, and Canada, so the report covers your in-scope users only. And presence describes what someone's status showed, not why. We treat it as evidence for a conversation, not a verdict, which is why anomaly flags always show the math behind them.
For background on reading the past at all, start with the pillar on how to see Teams status history. When you are ready to compare what each plan retains, see /pricing.
If a presence report is something you need on a regular basis, see how Presify works or start with one Microsoft sign-in.