Files
Backup-Dashboard/collectors/veeam/tests/MockVeeam.ps1
T
kyleandClaude Opus 5.5 9ae93cfbc2 Report Veeam backup copy job sessions
VBR 12+ backup copy jobs showed as Unknown. Get-VBRJob returns the copy
(policy) job, but Get-VBRBackupSession only returns sessions of its
hidden worker jobs, whose JobId matches no listed job, so they were
dropped. Confirmed on a VBR 13.0.2 server with the new diagnostics
script.

- File worker sessions under their policy job via
  Session.GetJob().PolicyJobId (looked up once per worker job), and
  record the source job in details.copied_from
- Add Get-VeeamCollectorDiagnostics.ps1, a read-only report of jobs,
  unmatched sessions and their link properties
- Mock: backup copy policy/worker case and a session from a deleted job

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 14:01:56 -06:00

84 lines
4.5 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Stand-ins for the Veeam cmdlets, shaped like the real objects' properties the collector reads.
# Dot-source this before running the collector to try it without a VBR server:
#
# . ./tests/MockVeeam.ps1
# ./Send-VeeamBackupStatus.ps1 -ConfigPath ./tests/config.json -DryRun
# Fixed to the top of the hour, and IDs derived from names/times, so repeated runs see the same
# jobs and sessions, like a real server
$now = Get-Date -Minute 0 -Second 0 -Millisecond 0
function New-StableGuid([string]$Seed) {
[guid]::new([Security.Cryptography.MD5]::Create().ComputeHash([Text.Encoding]::UTF8.GetBytes($Seed)))
}
$notSet = Get-Date '1900-01-01'
function New-MockJob($Name, $Type, $NextRun, [bool]$Enabled = $true) {
[pscustomobject]@{
Id = New-StableGuid $Name; Name = $Name; JobType = $Type
IsScheduleEnabled = $Enabled
ScheduleOptions = [pscustomobject]@{ NextRun = $NextRun }
}
}
function New-MockSession($Job, $Start, $End, $State, $Result, $Reason = '', $Tasks = @(), $LogRecords = @(), $Size = 0) {
$s = [pscustomobject]@{
Id = New-StableGuid "$($Job.Name)|$($Start.Ticks)"; JobId = $Job.Id; JobName = $Job.Name
CreationTime = $Start; EndTime = $End; State = $State; Result = $Result
IsRetryMode = $false
Info = [pscustomobject]@{ Reason = $Reason }
BackupStats = [pscustomobject]@{ BackupSize = $Size; DataSize = $Size * 3 }
Logger = [pscustomobject]@{ Records = $LogRecords }
Tasks = $Tasks
}
$s.Logger | Add-Member ScriptMethod GetLog { [pscustomobject]@{ UpdatedRecords = $this.Records } }
$s | Add-Member ScriptMethod GetTaskSessions { $this.Tasks }
$s
}
function New-MockTask($Name, $Status, $Reason = '') {
[pscustomobject]@{ Name = $Name; Status = $Status; Info = [pscustomobject]@{ Reason = $Reason } }
}
$global:MockJobs = @(
(New-MockJob 'File Server – Nightly' 'Backup' $now.Date.AddDays(1).AddHours(22)),
# Older VBR versions return NextRun as a culture-formatted string
(New-MockJob 'SQL01 – Logs' 'Backup' $now.AddMinutes(40).ToString()),
(New-MockJob 'Offsite Copy' 'BackupSync' $null),
(New-MockJob 'Old Exchange' 'Backup' $now.AddDays(1) $false),
# VBR 12+ backup copy job (immediate mode, no schedule): the "policy" job Get-VBRJob returns
(New-MockJob 'Cloud Copy' 'SimpleBackupCopyPolicy' $null)
)
$fs, $sql, $copy, $old, $cloud = $global:MockJobs
# Its hidden worker job, one per source job. Get-VBRJob doesn't return it, and Get-VBRBackupSession
# returns only the worker's sessions. Shape taken from a real VBR 13 server.
$cloudWorker = [pscustomobject]@{
Id = New-StableGuid 'Cloud Copy\File Server – Nightly'; Name = 'Cloud Copy\File Server – Nightly'
JobType = 'SimpleBackupCopyWorker'; PolicyJobId = $cloud.Id
}
function New-MockWorkerSession($Start, $End, $Result) {
$s = New-MockSession $cloudWorker $Start $End 'Stopped' $Result -Size 40GB
$s | Add-Member ScriptMethod GetJob { $cloudWorker }
$s
}
$global:MockSessions = @(
(New-MockSession $fs $now.AddDays(-1).AddHours(-2) $now.AddDays(-1).AddHours(-1) 'Stopped' 'Success' -Size 128GB -Tasks @(
(New-MockTask 'FS01' 'Success'), (New-MockTask 'FS02' 'Success'))),
(New-MockSession $fs $now.AddMinutes(-20) $notSet 'Working' 'None' -Tasks @((New-MockTask 'FS01' 'InProgress'))),
(New-MockSession $sql $now.AddHours(-1) $now.AddMinutes(-55) 'Stopped' 'Warning' -Size 2GB `
-Tasks @((New-MockTask 'SQL01' 'Warning' 'Failed to truncate transaction logs for database "ERP_PROD"'))),
(New-MockSession $copy $now.AddHours(-5) $now.AddHours(-4) 'Stopped' 'Failed' 'Error: Unable to connect to repository NAS02' `
-LogRecords @(
[pscustomobject]@{ Title = 'Preparing backup chain'; Status = 'ESucceeded' },
[pscustomobject]@{ Title = 'Network path not found (0x80070035)'; Status = 'EFailed' })),
(New-MockSession $old $now.AddDays(-10) $now.AddDays(-10).AddHours(1) 'Stopped' 'Success'), # outside 48h lookback
(New-MockWorkerSession $now.AddDays(-1).AddMinutes(-55) $now.AddDays(-1).AddMinutes(-30) 'Success'),
(New-MockWorkerSession $now.AddMinutes(-55) $now.AddMinutes(-35) 'Warning'),
# A session from a job the collector doesn't know (e.g. deleted): must be ignored, not crash
(New-MockSession ([pscustomobject]@{ Id = New-StableGuid 'gone'; Name = 'Deleted job' }) $now.AddHours(-2) $now.AddHours(-1) 'Stopped' 'Success')
)
function Get-VBRJob { [CmdletBinding()] param() $global:MockJobs }
function Get-VBRBackupSession { [CmdletBinding()] param() $global:MockSessions }