๐ Recipe ยท SharePoint & OneDrive
Report SharePoint Sites with File Counts and Storage Usage
Inventory every SharePoint site in your tenant with item counts and storage consumption in MB
Complexity
Intermediate
Impact
read-only + reporting + capacity-planning + sharepoint + audit
Context
Why This Matters
SharePoint storage in Microsoft 365 is a finite, paid resource. Tenants receive a base allocation (typically 1 TB + 10 GB per licensed user) plus any add-on storage SKUs. Over time, abandoned team sites, video-heavy document libraries, and legacy migration landing zones can silently consume that pool โ leading to surprise overage charges, failed uploads, and user-facing errors like Storage quota exceeded.
This recipe produces a tenant-wide inventory of every SharePoint site with two key metrics per site: item count (files and folders at the root level of the default document library) and storage used in MB. Run it as part of a quarterly capacity review, before purchasing additional SharePoint storage, or when investigating which sites are driving growth. The report is also useful during mergers, divestitures, and data-lifecycle audits where you need to justify retention or archival decisions.
Expected Outcomes
What you'll have when you finish
- A sorted list of every SharePoint site in the tenant (communication sites, team sites, the root site, hub sites, and the Content Type Hub).
- Storage consumed per site in megabytes, pulled from the drive
quota.usedproperty or the root foldersize. - File/folder count at the default document library root for each site.
- A grand total of storage used across the tenant.
- Exportable CSV output for capacity planning, chargeback, or executive reporting.
Risks & Considerations
Things to watch out for
- Permissions:
Sites.Read.Allis required to enumerate all sites. The/sites/getAllSitesendpoint is inconsistent and often returns 403 โ use/sites?search=*instead. - Root-level counts only:
folder.childCountat the root is not a recursive file count. Sites with nested folders will under-report unless you recurse or use the SharePoint admin Usage report. - Quota data is eventually consistent: The
quota.usedvalue on a drive can lag by several hours. For exact chargeback numbers, cross-reference with the SharePoint admin center's Active Sites report. - Throttling: Large tenants (1000+ sites) will hit Graph throttling (HTTP 429). Add retry-with-backoff logic and respect the
Retry-Afterheader. - Personal OneDrive sites are excluded by the search endpoint by default. If you need them, query
/users/{id}/driveseparately. - Don't modify: This is a read-only audit. Do not combine with bulk-delete operations without an explicit owner sign-off and a recycle-bin retention check.
Required Permissions
| Permission | Why It's Needed |
|---|---|
| Sites.Read.All | Required to enumerate every SharePoint site in the tenant and read its metadata. |
| Files.Read.All | Required to read drive and driveItem properties (size, childCount, quota) across all sites. |
| Reports.Read.All | Optional โ needed if you pull storage data from the SharePoint Usage reports instead of per-drive quota. |
The fastest way to get this done: just ask Dex. Copy the prompt below and paste it into your Dex conversation.
For IT Admins
Paste into Dex Pro
Generate the report from the SharePoint admin center
The GUI path gives you most of the data without scripting, though item counts are aggregated per library rather than per site.
- Sign in to the Microsoft 365 Admin Center as a Global Administrator or SharePoint Administrator.
- In the left nav, expand to open the SharePoint admin center.
- Go to .
- Click the Storage used (GB) column header to sort descending โ the largest sites float to the top.
- To add the file-count metric, click Customize columns in the toolbar and enable the Files column (if available in your tenant). Some tenants expose this via the Files viewed or edited usage column instead.
- Click Export in the toolbar to download a CSV of all sites with URL, storage used, storage limit, last activity date, and owner.
- For more granular metrics, go to and . The site usage report includes file counts, active file counts, and storage used per site.
- Export both reports and join them on
Site URLin Excel or Power BI to build the combined view.
Tip: The Active sites list caches data and may be up to 24 hours stale. Usage reports refresh every 1โ2 days.
Build the report with Microsoft Graph
Three Graph calls per site: list all sites, list drives per site, and inspect the drive root. Aggregate the results client-side.
Step 1 โ Enumerate all sites
The reliable way to list every site is a wildcard search. The getAllSites endpoint frequently returns 403 even with full permissions.
GET https://graph.microsoft.com/v1.0/sites?search=*&$select=id,displayName,name,webUrlResponse:
{
"value": [
{
"id": "contoso.sharepoint.com,<siteGuid>,<webGuid>",
"displayName": "Marketing Internal",
"webUrl": "https://contoso.sharepoint.com/sites/MarketingInternal"
}
]
}Step 2 โ Get the default drive for each site
GET https://graph.microsoft.com/v1.0/sites/{site-id}/drives?$select=id,name,quotaThe quota.used property returns storage consumption in bytes. Not all drives populate quota data โ fall back to the root folder size if quota is empty.
Step 3 โ Get root item count and fallback size
GET https://graph.microsoft.com/v1.0/drives/{drive-id}/root?$expand=children($select=id,name,file,folder)Key fields in the response:
sizeโ total bytes stored in the library (root + all descendants).folder.childCountโ number of items at the root level only.children[]โ each root item withfileorfolderfacet.
Step 4 โ Convert and aggregate
Convert bytes to MB: MB = bytes / 1048576. Sort by size descending and sum for a tenant total.
Handling throttling
If you receive HTTP 429, read the Retry-After header (seconds) and pause before retrying. Batch drive-root calls with $batch (max 20 requests per batch) to reduce round trips in large tenants.
Automate with PowerShell and Microsoft Graph
The script below uses the Microsoft.Graph PowerShell SDK to produce the same report programmatically. It handles pagination, quota fallback, and exports to CSV.
Prerequisites
- Install the Graph SDK:
Install-Module Microsoft.Graph -Scope CurrentUser - You need SharePoint Administrator or Global Reader role.
- Consent to
Sites.Read.AllandFiles.Read.Allon first run.
How the script works
Connect-MgGraphwith the required scopes.Get-MgSite -Search '*'enumerates every site (auto-paginates with-All).- For each site,
Get-MgSiteDrivereturns its document libraries. - For the default drive, the script inspects
Quota.Usedfirst, then falls back to the rootSizeproperty. Get-MgDriveRoot -ExpandProperty Childrenreturns the child count.- Results are sorted by size and written to
SharePointSitesReport.csv.
Running it
.\Get-SharePointSiteUsageReport.ps1 -OutputPath "C:\Reports\SPSites.csv"The script prints a summary table to the console and writes the full CSV at the path you specify.
Next steps