Admins (Microsoft 365 sign-in names in BACKUP_DASH_ADMINS) get an Admin link to /admin.html, where they can create, list and revoke the API keys collectors use, instead of running manage.py on the server. Backend - /api/v1/admin/keys (list, create, revoke), admins only (403 otherwise); the user comes from the headers nginx sets after sign-in - Changes need an X-Requested-By header, which another site's page can't add, so a signed-in admin's browser can't be used to forge them - A new key is returned once; only its hash is stored. Names are unique for good, so revoked keys' history stays unambiguous - Keys record who created/revoked them and the company they last reported for (schema v2; databases migrate automatically on start) - /api/v1/me reports is_admin; manage.py shares the key code and records itself as creator/revoker Frontend - admin.html / admin.js: name validation shown after interaction (:user-invalid, aria-invalid kept in sync), the one-time key with a copy button (falls back to selecting it if clipboard access is refused), a key table flagging keys quiet for over 24 hours, and revoking confirmed in a <dialog>; results announced in a status region - Shared el() and signed-in helpers moved to dom.js / signed-in.js - Mock mode (?mock=1) includes sample keys Tested: 15 new backend tests (access, forged requests, names, duplicates, revoking, last-used company, v1 -> v2 upgrade); in the browser, every admin flow in mock mode and at phone width; end to end through the nginx config with the real API (a key created on the API works for ingest; revoking it makes ingest 401; non-admins see an explanation and no Admin link). Co-Authored-By: Claude Opus 5.5 <[email protected]>
72 lines
3.9 KiB
Markdown
72 lines
3.9 KiB
Markdown
# Windows Server Backup collector
|
|
|
|
A PowerShell script that runs on each server using Windows Server Backup (WSB) and reports its
|
|
backups to the dashboard. Each server appears as one job, named `<SERVER> - Windows Server Backup`
|
|
by default.
|
|
|
|
> **Checked against:** Server 2019 Hyper-V host backing up VMs, successful backups only.
|
|
> Not yet seen on a real server: a failed backup, a failed VM or volume, or a backup in progress.
|
|
> Those paths are written to the same object model, but if one looks wrong, run
|
|
> `Get-WsbCollectorDiagnostics.ps1` while it's in that state and send the output.
|
|
|
|
## Install (on the server, as an administrator)
|
|
|
|
Requires the Windows Server Backup feature with its PowerShell module
|
|
(`Install-WindowsFeature Windows-Server-Backup`). Runs under Windows PowerShell 5.1
|
|
(`powershell.exe`), which that module targets.
|
|
|
|
1. Create a key for this server on the dashboard's **Admin** page, or on the dashboard host:
|
|
```bash
|
|
python manage.py create-key wsb-acme-dc01
|
|
```
|
|
2. Copy the whole `collectors` folder to the server (the installer needs `common`
|
|
as well as this folder), then from `collectors\wsb` run:
|
|
```powershell
|
|
.\Install-WsbCollector.ps1 -ApiUrl https://backups.example.com -Tenant "Acme Corp"
|
|
```
|
|
Add `-JobName "Domain Controller"` to choose the name shown on the dashboard. It prompts for the
|
|
key, then:
|
|
- writes `C:\ProgramData\BackupDashboard\wsb-collector.json` (readable only by SYSTEM and Administrators)
|
|
- copies the script to `C:\Program Files\BackupDashboard\`
|
|
- registers the scheduled task **Backup Dashboard - WSB collector** (SYSTEM, every 60 minutes)
|
|
3. Preview the payloads, then backfill 30 days so the history view is populated straight away:
|
|
```powershell
|
|
powershell.exe -File 'C:\Program Files\BackupDashboard\Send-WsbBackupStatus.ps1' -DryRun
|
|
powershell.exe -File 'C:\Program Files\BackupDashboard\Send-WsbBackupStatus.ps1' -LookbackHours 720
|
|
```
|
|
|
|
It can be installed alongside the other collectors: it uses its own config, state, log and task.
|
|
Re-run the installer to change settings or update the script. It also installs
|
|
`BackupDashboard.Collector.psm1`, the code shared by all collectors, next to the script.
|
|
|
|
## What it sends
|
|
|
|
| Dashboard | Windows Server Backup |
|
|
|---|---|
|
|
| Company | `Tenant` from the config |
|
|
| Job | One per server, ID `wsb:<computer name>`, so changing `JobName` renames rather than duplicates it |
|
|
| Run | One per backup job from `Get-WBJob`, identified by its start time (WSB jobs have no ID). Restores are ignored. `details.items` lists what was backed up: the VMs for a Hyper-V backup, otherwise volumes |
|
|
| Status | Error HRESULT → **Failed**. Success, but a detailed error or a failed item (e.g. one volume) → **Warning**. Cancelled or unrecognised → **Warning**. In progress → **Running** |
|
|
| Started / finished | Job start / end time. WSB gives these as local-time text to the minute, in the server's date format; the collector parses them with that format |
|
|
| Next scheduled | `Get-WBSummary`'s `NextBackupTime`. Empty when there's no scheduled backup |
|
|
| Message | Error description, error codes (as `0x8XXXXXXX`), failed VMs/volumes, and the failure log path |
|
|
| Size | Bytes processed across the backup's items |
|
|
|
|
Each run covers the last 48 hours (`LookbackHours`). Runs already delivered are recorded in
|
|
`wsb-collector.state.json`.
|
|
|
|
## Troubleshooting
|
|
|
|
- Log: `C:\ProgramData\BackupDashboard\wsb-collector.log`. Exit codes: `0` OK, `1` some runs
|
|
failed to send (retried next run), `2` setup failed (config or WindowsServerBackup module).
|
|
- Wrong status, times or messages: run `.\Get-WsbCollectorDiagnostics.ps1` (read-only). It prints
|
|
the real structure of what the cmdlets return, plus recent `Microsoft-Windows-Backup` events to
|
|
compare times against.
|
|
|
|
## Testing without Windows Server Backup
|
|
|
|
```powershell
|
|
. ./tests/MockWsb.ps1 # or: . ./tests/MockWsb.ps1 -WithRunningJob
|
|
./Send-WsbBackupStatus.ps1 -ConfigPath ./my-test-config.json -DryRun
|
|
```
|