A lightweight, single-page operational dashboard for SharePoint Server Subscription Edition, hosted entirely within a SharePoint document library. Two files:
| File | Purpose |
|---|---|
Export-SPDashboardData.ps1 |
PowerShell script — collects farm statistics and uploads dashboard-data.txt (JSON) to the document library |
sp-dashboard.aspx |
Static dashboard page — reads dashboard-data.txt from its own library location and renders it in the browser |
The dashboard has no runtime dependencies beyond a modern browser — no JavaScript frameworks, no CDN references, no server-side code, and nothing to install on the farm. The colour theme is defined as CSS variables at the top of sp-dashboard.aspx and is easy to rebrand.
Scheduled task (weekly, farm admin account)
│
│ Export-SPDashboardData.ps1
│ ├── SharePoint server object model → users, site collections, storage, content DBs
│ ├── Usage & Health DB (direct SQL) → active users in the last N days
│ └── Search Service Application → index item count, crawl status
▼
DashboardLibrary/dashboard-data.txt (JSON payload, uploaded via the server object model)
▲
│ fetch('dashboard-data.txt')
│
DashboardLibrary/sp-dashboard.aspx ← users browse here
Both files live in the same document library, so the page fetches its data with a relative URL and inherits the library's own permissions. There is no separate service, database, or endpoint to secure: viewers see the dashboard if and only if they can read the library.
| KPI Card | Source |
|---|---|
| Total Users | Distinct non-system accounts across all web application site collections |
| Active Users (7 d) | Distinct authenticated requests in the Usage & Health logging database |
| Site Collections | Count across all configured web applications |
| Total Storage | Aggregated storage consumed, in TB |
| Content Databases | Count across all configured web applications |
| Search Index | Item count from the Search Service Application |
Below the KPI cards:
- Storage — Largest Site Collections — quota utilisation bar chart for the largest site collections by storage consumed (top 10 by default, configurable via
TopSiteCount), aggregated across all configured web applications. Farm-wide totals and quota warnings still cover every site collection. Bars are coloured amber at ≥ 75 % and red at ≥ 90 % - Weekly Notes & Actions — warnings generated automatically by the script (quota alerts, crawl status) plus any manual entries
The footer shows the report date, the script version that produced the data, and a Live data / Error badge.
Note: the export also writes a per-database inventory (
contentDBs— name, SQL server, site count, site limit, disk size) intodashboard-data.txt. The current page renders the content-database count as a KPI but does not yet lay out the full table; the data is there if you want to add one.
- SharePoint Server Subscription Edition (WFE or App server)
- PowerShell 5.1 or later
Microsoft.SharePoint.PowerShellsnap-in (loaded automatically)- Farm administrator service account
db_datareaderon the Usage & Health Data Collection database (granted automatically to farm admins)
One-time setup per environment:
- Create or choose a document library and upload
sp-dashboard.aspxto it. (Uploading an.aspxrequires the Add and Customize Pages permission; viewers only need read access.) - Configure the scheduled task (below) with
-LibraryUrlpointing at the same library. - Browse to
https://.../DashboardLibrary/sp-dashboard.aspx.
Encoding warning:
sp-dashboard.aspxmust remain saved as UTF-8 with BOM. SharePoint's ASPX page parser reads the file before the<meta charset>tag applies; without a BOM it assumes ANSI and garbles every dash and accented character (e.g.—renders asâ€"). If you edit the file, keep the BOM.
Why
dashboard-data.txtand not.json?jsonis in the web application'sBlockedASPNetExtensionslist by default, so SharePoint returns an error page instead of serving.jsonfiles from libraries. The script uploads the data as.txt(contents are still JSON) and the page fetches that name. Similarly, the dashboard page is an.aspxrather than.htmlbecause Strict browser file handling (the default) forces.htmlfiles to download instead of render. Neither workaround requires farm configuration changes.
Run the script as a scheduled task or interactively on any SharePoint server in the farm.
Single web application
.\Export-SPDashboardData.ps1 `
-LibraryUrl "https://intranet.contoso.com/sites/ops/DashboardLibrary" `
-WebApplicationUrls "https://intranet.contoso.com" `
-UsageDatabaseServer "SQL01\SHAREPOINT" `
-CustomerName "Contoso" `
-Environment "Prod"Multiple web applications (results are aggregated)
.\Export-SPDashboardData.ps1 `
-LibraryUrl "https://intranet.contoso.com/sites/ops/DashboardLibrary" `
-WebApplicationUrls @("https://intranet.contoso.com", "https://mysite.contoso.com", "https://extranet.contoso.com") `
-UsageDatabaseServer "SQL01\SHAREPOINT"| Parameter | Required | Default | Description |
|---|---|---|---|
LibraryUrl |
Yes | — | URL of the SharePoint document library (or folder within one) hosting sp-dashboard.aspx; the dashboard data is uploaded there as dashboard-data.txt |
UsageDatabaseServer |
Yes | — | SQL Server instance hosting the Usage & Health database |
WebApplicationUrls |
No | http://intranet |
One or more web application root URLs to report on |
UsageDatabaseName |
No | Usage |
Name of the Usage & Health Data Collection database |
CustomerName |
No | — | Customer name shown as the dashboard report title |
Environment |
No | — | Environment label (e.g. Dev, Pre-Prod, Prod) shown as a colour-coded badge next to the customer name (green = Prod, coral = Pre-Prod/UAT/Staging, blue = Dev/Test/Sandbox, grey = anything else) |
ActiveDaysWindow |
No | 7 |
Days to look back when counting active users |
StorageWarnPct |
No | 75 |
Quota % at which a site collection is flagged as a warning |
StorageCritPct |
No | 90 |
Quota % at which a site collection is flagged as critical |
TopSiteCount |
No | 10 |
Number of largest site collections (by storage) listed on the dashboard |
Run weekly (e.g. Monday 07:00) under a farm administrator service account:
Program: powershell.exe
Arguments: -NonInteractive -ExecutionPolicy Bypass -File "C:\Scripts\Export-SPDashboardData.ps1"
-LibraryUrl "https://intranet.contoso.com/sites/ops/DashboardLibrary"
-WebApplicationUrls @('https://intranet.contoso.com','https://mysite.contoso.com')
-UsageDatabaseServer "SQL01\SHAREPOINT"
-CustomerName "Contoso" -Environment "Prod"
The script carries a version number in $ScriptVersion (current: 1.0), with a matching version history in the .NOTES section of the comment-based help. The version is written into the dashboard data (scriptVersion) and displayed in the dashboard footer, so you can always see which script version produced the data on screen.
When changing the script, update both $ScriptVersion and the version history.
If dashboard-data.txt cannot be retrieved from the library, the dashboard shows an explicit error panel (with the underlying fetch error) instead of rendering any data, and an "Error — no data loaded" badge in the footer. The usual causes are the scheduled task not having run yet, or the viewer lacking read access to the data file.
The script itself fails fast ($ErrorActionPreference = "Stop"), but degrades rather than aborting where a farm can legitimately refuse a read: site collections that deny enumeration (eDiscovery sites, site masters) are skipped with a warning, and a failed Usage-database query or Search lookup records a note on the dashboard rather than stopping the export — the active-user KPI reads N/A, and the search index count falls back to 0.
- No credentials are stored anywhere. The SQL connection uses
Integrated Security=SSPI, so it runs as whatever account the scheduled task uses. - The dashboard page is static — it has no server-side code and makes exactly one request, to
dashboard-data.txtin its own library. - Access control is entirely the document library's. Anyone who can read the library can read the farm statistics, so put the library somewhere appropriate for that.
- The JSON payload contains site collection URLs, content database names and SQL server names. Bear that in mind when choosing who can read the library.
Issues and pull requests are welcome. If you change sp-dashboard.aspx, keep it saved as UTF-8 with BOM (see the encoding warning above) — .gitattributes sets * -text to stop Git rewriting line endings, but your editor can still strip the BOM.
If you change the script, update both $ScriptVersion and the version history in the .NOTES block.
MIT — © 2026 Neil Johnson.