PowerShell script for the VB365 server, run hourly as a SYSTEM scheduled
task (Windows PowerShell 5.1 by default, -PwshPath for PowerShell 7).
One dashboard job per VB365 backup job and backup copy job.
- Sessions from Get-VBOJobSession (and Get-VBOCopyJobSession where
available) within the lookback window; status from session Status,
message from the session log's warning/error lines, size from
Statistics.TransferredData ("1.5 GB" -> bytes)
- One VB365 server can protect several Microsoft 365 organizations, so
the dashboard company is chosen per job: OrganizationTenants mapping,
else Tenant, else the organization's name
- Next run from the job's NextRun; empty for disabled jobs
- Get-Vb365CollectorDiagnostics.ps1 dumps jobs and sessions, showing
each DateTime's Kind (local vs UTC); installer adapted from MARS
Not yet run against a real server.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
86 lines
3.9 KiB
Markdown
86 lines
3.9 KiB
Markdown
# Veeam Backup for Microsoft 365 collector
|
|
|
|
A PowerShell script that runs on the Veeam Backup for Microsoft 365 (VB365) server and reports its
|
|
backup jobs (and backup copy jobs) to the dashboard, one dashboard job per VB365 job.
|
|
|
|
> **Not yet checked against a real server.** The cmdlets are VB365's own (`Get-VBOJob`,
|
|
> `Get-VBOJobSession`), but the properties of the objects they return aren't fully documented.
|
|
> Before installing on the first server, run `Get-Vb365CollectorDiagnostics.ps1` and the collector
|
|
> with `-DryRun` (see below) to confirm what it reads.
|
|
|
|
## Which company a job appears under
|
|
|
|
One VB365 server can protect several Microsoft 365 organizations, so the company is picked per job
|
|
from the job's organization:
|
|
|
|
1. `OrganizationTenants` maps an organization name (as `Get-VBOOrganization` shows it, e.g.
|
|
`acme.onmicrosoft.com`; not case-sensitive) to a dashboard company.
|
|
2. Otherwise `Tenant`, for a VB365 server dedicated to one client.
|
|
3. Otherwise the organization's own name.
|
|
|
|
Changing a job's company later creates a new dashboard job under the new company; delete the old
|
|
one with `python manage.py delete-job <id>`.
|
|
|
|
## Install (on the VB365 server, as an administrator)
|
|
|
|
1. On the dashboard host, create a key for this server:
|
|
```bash
|
|
python manage.py create-key vb365-01
|
|
```
|
|
2. Copy this folder to the server and run one of:
|
|
```powershell
|
|
# VB365 server for one client
|
|
.\Install-Vb365Collector.ps1 -ApiUrl https://backups.example.com -Tenant "Acme Corp"
|
|
|
|
# Shared VB365 server
|
|
.\Install-Vb365Collector.ps1 -ApiUrl https://backups.example.com -OrganizationTenants @{
|
|
'acme.onmicrosoft.com' = 'Acme Corp'
|
|
'bluewater.onmicrosoft.com' = 'Bluewater Dental'
|
|
}
|
|
```
|
|
It prompts for the key, then:
|
|
- writes `C:\ProgramData\BackupDashboard\vb365-collector.json` (readable only by SYSTEM and Administrators)
|
|
- copies the script to `C:\Program Files\BackupDashboard\`
|
|
- registers the scheduled task **Backup Dashboard - VB365 collector** (SYSTEM, every 60 minutes)
|
|
|
|
It runs under Windows PowerShell 5.1. If your VB365 version's module needs PowerShell 7, add
|
|
`-PwshPath 'C:\Program Files\PowerShell\7\pwsh.exe'`.
|
|
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-Vb365BackupStatus.ps1' -DryRun
|
|
powershell.exe -File 'C:\Program Files\BackupDashboard\Send-Vb365BackupStatus.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 (including the organization mapping) or update the script.
|
|
|
|
## What it sends
|
|
|
|
| Dashboard | VB365 |
|
|
|---|---|
|
|
| Company | See above |
|
|
| Job | Each backup job and backup copy job. The job's GUID is the ID, so renaming it in VB365 doesn't duplicate it |
|
|
| Status | Session status: Success / Warning / Failed. Running or queued → **Running**. Stopped (cancelled) or unrecognised → **Warning** |
|
|
| Started / finished | Session `CreationTime` / `EndTime` |
|
|
| Next scheduled | Job's `NextRun`. Empty for disabled jobs |
|
|
| Message | Warning and error lines from the session log |
|
|
| Size | Data transferred (`Statistics.TransferredData`) |
|
|
| Details | Organization, objects processed, job kind (`backup` / `copy`) |
|
|
|
|
Each run covers the last 48 hours (`LookbackHours`). Sessions already delivered are recorded in
|
|
`vb365-collector.state.json`.
|
|
|
|
## Troubleshooting
|
|
|
|
- Log: `C:\ProgramData\BackupDashboard\vb365-collector.log`. Exit codes: `0` OK, `1` some jobs
|
|
failed to send (retried next run), `2` setup failed (config or VB365 module).
|
|
- Wrong status, times or messages: run `.\Get-Vb365CollectorDiagnostics.ps1` (read-only). It prints
|
|
the real structure of jobs and sessions, including whether each date is local or UTC.
|
|
|
|
## Testing without VB365
|
|
|
|
```powershell
|
|
. ./tests/MockVb365.ps1
|
|
./Send-Vb365BackupStatus.ps1 -ConfigPath ./my-test-config.json -DryRun
|
|
```
|