Executive summary from your tenant

04 Nov 2026

The monthly IT report your CFO reads, written from your tenant

Your CFO doesn't want a dashboard. They want one page, every month, in words they can repeat in a board meeting: what Azure cost, what licences are wasted, whether the company is safe, whether the laptops are fine. Most IT teams build that page by hand from five admin centres, and the numbers stop matching the portals by the second month.

The GraphPaaS connector for Claude has an Executive summary prompt in its menu. It reads six domains, writes for a non-technical reader and ends with three risks and three wins. We ran it for October on Fabrikam HQ, our demo tenant (synthetic people, real tool calls, data collected on 31 October at 21:45 UTC). Three of the six lines needed a second look before they were fit for a CFO, and that second look is what this article is about.

€2,629.66
Azure, October to date
€5,280
a year on 10 idle licences
35 of 42
people with MFA registered
31 of 36
devices compliant

A licence line that says 1.8%

The brief starts with licence utilisation: seats assigned against seats bought. It is the number a CFO grasps fastest, and the first one that came back wrong.

You ask

Write October's executive summary for Fabrikam HQ.

Claude calls
get_metrics(domain="licences", tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e",
            aggregate=["sum:consumed", "sum:total", "sum:free"])
→ consumed 187 · total 10,230 · free 10,043
get_metrics(domain="licences", tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e",
            where={"total": {"<": 10000}},
            aggregate=["sum:consumed", "sum:total", "sum:free"])
→ consumed 178 · total 230 · free 52
Claude answers

Summed as is, the tenant uses 1.8% of its licences. That's the Power Automate Free row: 10,000 seats, 9 used, nothing paid. Leaving it out, 178 of 230 paid seats are assigned (77%), and 52 sit unassigned across nine products.

Graph reports every SKU the tenant holds through subscribedSku: consumedUnits is the licences assigned, prepaidUnits the ones held. The row doesn't say whether anyone pays for them, so a free self-service SKU sits next to Microsoft 365 E3 with the same weight. One sum across all of them is a number nobody should read aloud.

Waste is a count until someone gives it a price

The prompt asks

Who holds a licence and did nothing with it in 90 days, and what does that cost?

Claude calls
get_metrics(domain="licence_waste", tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e",
            where={"last_activity": null})
→ 5 rows
get_metrics(domain="licence_waste", tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e",
            where={"last_activity": {"<": "2026-08-03"}})
→ 5 rows
licence_advisor(tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e", state="remove", window_days=90)
→ catalogue "sample catalogue" · E3 €432/yr · EMS E3 €120/yr
Claude answers

10 people hold a licence with no activity in 90 days: 5 show none at all, 5 were last active between March and early July. 8 of them hold E3 plus EMS E3, 2 hold E3 alone. At the catalogue's prices that is €5,280 a year. The 8 unassigned E3 and EMS seats add €1,896; the other unassigned products have no price in the catalogue.

A CFO reads money, and the prompt deliberately has no price list. The connector's rule is that Claude never invents a licence price: it takes them from the catalogue the organisation uploaded, or asks. The demo uses a sample catalogue, so treat €5,280 as the arithmetic, not as Fabrikam's contract. With your own prices in, the line becomes yours. Who those ten people are, and why "no activity" can hide a date Microsoft dropped, is in our licence review in one prompt.

Azure, counted once

The brief totals spend with sum:cost grouped by value. The breakdown domain stores the month to date five ways (by service, resource type, resource group, region and charge type), so grouped by value alone the top three rows were "Usage" (a charge type, €2,629.68), "westeurope" (a region, €2,277.52) and then "Virtual Machines". A sum over every row would be five times the bill.

The prompt asks

What did Azure cost this month, and where did it go?

Claude calls
get_metrics(domain="bills_breakdown", tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e",
            where={"dimension": "service"}, group_by="value",
            aggregate=["sum:cost"], order_by="-sum:cost")
→ 9 services · Virtual Machines 1,372.73 · Azure SQL Database 489.41 ·
  App Service 290.05 · Application Gateway 184.17 · Storage 171.60 · …
Claude answers

Azure cost €2,629.66 in October up to the 31st, in EUR. Virtual machines are just over half of it (€1,372.73), databases about a fifth (€489.41). Everything else is under €300 a line.

The figure comes from Cost Management's Query API with the MonthToDate timeframe, one query per dimension. Read on the 31st, it is October less a few hours; read on the 15th it is half a month, and the page should say so. The two cents between €2,629.66 and €2,629.68 are rounding across rows, not money.

ONE PAGE · SIX LINES · THE CALL BEHIND EACH October · Fabrikam HQ what the CFO reads Azure €2,629.66 77% of paid seats used €5,280/yr idle licences MFA 35 of 42 Devices 31 of 36 compliant Secure Score 61.2% bills_breakdown · dimension = service unfiltered: the month counted five times licences · total < 10,000 unfiltered: 1.8%, a free SKU's 10,000 seats licence_waste × licence_advisor catalogue no catalogue: a count, never an invented price mfa_registration · group_by mfa_registered registered, not necessarily allowed by policy devices · group_by compliance_state Intune-managed devices only secure_score · kind = summary pct against Microsoft's peer average, not points

Security in a sentence a CFO can repeat

The prompt asks

Are we protected, are the laptops fine, and did Microsoft break anything?

Claude calls
get_metrics(domain="mfa_registration", tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e",
            group_by="mfa_registered")
→ true 35 · false 7          (1 October: 34 · 8)
get_metrics(domain="devices", tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e",
            group_by="compliance_state")
→ compliant 31 · noncompliant 5   (1 October: 32 · 4)
get_metrics(domain="secure_score", tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e",
            where={"kind": "summary"})
→ pct 61.2 · avg_alltenants 48.7 · avg_totalseats 52.1
get_metrics(domain="service_health", tenant_id="ce48e256-019f-4f8c-b951-0c52d1d65b8e")
→ 6 rows (3 open: 1 incident, 2 advisories)
Claude answers

35 of 42 people (83%) have a second sign-in factor, one more than on 1 October. 31 of 36 company devices meet the security rules, one fewer. Microsoft rates the tenant's security setup at 61.2%, against 52.1% for organisations of a similar size. One Microsoft incident is open: some users can't send Teams messages, since 31 October.

Three translations are hiding in that answer. "Second sign-in factor" is isMfaRegistered, which on the userRegistrationDetails resource means a strong method is registered, not necessarily one the methods policy allows; the stricter flag is isMfaCapable. "Organisations of a similar size" is the seat-count average that secureScore carries in averageComparativeScores; Microsoft's Secure Score comparison is anonymised, so it is a benchmark, not a ranking. And "incident" is a word Microsoft uses precisely: a serviceHealthIssue is either an incident or an advisory, and the two open advisories (mail delays through connectors, incomplete SharePoint search) stay off the page unless a user felt them.

The page it ends with

Claude answers · the summary, abridged

October at Fabrikam HQ. Azure cost €2,629.66, half of it virtual machines. 77% of the paid Microsoft 365 seats are in use. Security and devices held steady: one more person protected by a second factor, one more laptop out of line.

Three risks. Seven people have no second sign-in factor registered. Five devices don't meet the security rules. €5,280 a year goes on licences ten people haven't used in three months.

Three wins. The security score sits nine points above similar organisations. Three Microsoft service issues this month (Entra sign-ins, Intune enrolment, OneDrive sync) are already resolved. Most licences that are paid for are used.

No column names, no SKU part numbers, and every number on it is one of the receipts above. That's the check we'd keep doing before it goes to finance: pick any line, find its call. If a line has no call behind it, it came from the model, and it comes off the page.

The pattern
The numbers that went wrong were all sums: seats across SKUs, cost across dimensions, waste without a price. A total is only as honest as what was left out of it, so the summary should say what it left out. Run the same prompt on 1 December and the comparison is month on month. How the connector is set up in the first place is in GraphPaaS in Claude.
Sources
GraphPaaS

Write November's page from your own tenant: the executive summary is in the connector's menu.

Add the connector →

Newsletter

Get the next article by email

Practical M365 & Azure cost pieces like this one. No spam, unsubscribe anytime.