The Veeam, MARS, WSB and VB365 collectors each carried identical copies of logging, ISO time conversion, property lookup, posting to the API, config loading, TLS setup, the sent-runs state file and the 401 check, and their installers repeated the same key prompt, locked-down config, file copy and scheduled-task registration. These now live in collectors/common/BackupDashboard.Collector.psm1: - Initialize-Collector / Test-RunSent / Send-JobReport / Test-AuthRejected / Complete-Collector for collector runs - Write-Log, Get-ErrorText, ConvertTo-IsoTime, Get-FirstValue - Install-CollectorTask for the shared half of each installer Collectors find the module next to themselves (installed) or in ..\common (repo); installers copy it into Program Files beside the collector. The diagnostic scripts stay standalone single files. No behavior change: a harness ran each collector against its mock (12 scenarios: dry run, two real runs against a stub API, state file, logs, exit codes, rejected key, en-GB, backfill) before and after, and all 84 outputs are identical. Installers, run with stand-ins for the Windows-only commands, write identical configs and tasks; the only differences are the module being copied and the summary line naming the shell's path. Co-Authored-By: Claude Opus 5.5 <[email protected]>
89 lines
4.4 KiB
Markdown
89 lines
4.4 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.
|
|
|
|
> **Checked against:** VB365 8.4 under Windows PowerShell 5.1, a shared server protecting 11
|
|
> organizations: successful, warning and retried sessions. Not yet seen on a real server: a failed
|
|
> session, a session in progress, or a backup copy job. If one looks wrong, run
|
|
> `Get-Vb365CollectorDiagnostics.ps1` while it's in that state and send the output.
|
|
|
|
## 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 the whole `collectors` folder to the server (the installer needs `common`
|
|
as well as this folder), then from `collectors\vb365` 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. It also installs
|
|
`BackupDashboard.Collector.psm1`, the code shared by all collectors, next to 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 (items titled `[Warning] ...`, `[Failed] ...`), plus "Veeam will retry this job." when a retry is pending |
|
|
| Retries | VB365 runs a retry as a separate session, so it appears as its own run, marked `details.retry_of` (the session it retried). The retried run is marked `details.will_retry` |
|
|
| 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
|
|
```
|