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]>
This commit is contained in:
@@ -154,6 +154,17 @@ function Get-RunMessage($Session, [string]$Status, $Tasks) {
|
||||
return ($lines -join "`n")
|
||||
}
|
||||
|
||||
# VBR 12+ backup copy jobs: Get-VBRJob returns the copy (policy) job, but Get-VBRBackupSession
|
||||
# returns only the sessions of its hidden worker jobs, one per source job, never the policy's own.
|
||||
# Each worker job records its policy in PolicyJobId, so those sessions can be filed under it.
|
||||
function Get-PolicyJobId($Session, [hashtable]$KnownJobIds) {
|
||||
try {
|
||||
$policyId = [string]$Session.GetJob().PolicyJobId
|
||||
if ($policyId -and $KnownJobIds.ContainsKey($policyId)) { return $policyId }
|
||||
} catch { }
|
||||
return ''
|
||||
}
|
||||
|
||||
function ConvertTo-Run($Session, $Job) {
|
||||
$status = Get-RunStatus $Session
|
||||
$tasks = @()
|
||||
@@ -169,6 +180,11 @@ function ConvertTo-Run($Session, $Job) {
|
||||
if ($failedTasks) { $details.objects_failed = $failedTasks }
|
||||
if ($warningTasks) { $details.objects_warning = $warningTasks }
|
||||
try { if ($Session.IsRetryMode) { $details.retry = $true } } catch { }
|
||||
# Worker session of a backup copy job: say which source job it copied
|
||||
# (worker sessions are named "<copy job>\<source job>")
|
||||
if ($Session.JobId.ToString() -ne $Job.Id.ToString()) {
|
||||
$details.copied_from = ([string]$Session.JobName -split '\\')[-1]
|
||||
}
|
||||
|
||||
$run = [ordered]@{
|
||||
external_id = $Session.Id.ToString()
|
||||
@@ -238,11 +254,20 @@ try {
|
||||
$since = (Get-Date).AddHours(-$LookbackHours)
|
||||
$jobs = @(Get-VBRJob -WarningAction SilentlyContinue)
|
||||
|
||||
$jobIds = @{}
|
||||
foreach ($j in $jobs) { $jobIds[$j.Id.ToString()] = $true }
|
||||
|
||||
# Get-VBRBackupSession returns every session in the database, so fetch once and bucket by job
|
||||
$sessionsByJob = @{}
|
||||
$policyByWorker = @{} # worker job ID -> policy job ID ('' if it isn't a worker of a listed job)
|
||||
foreach ($s in Get-VBRBackupSession -WarningAction SilentlyContinue) {
|
||||
if ($s.CreationTime -lt $since) { continue }
|
||||
$key = $s.JobId.ToString()
|
||||
if (-not $jobIds.ContainsKey($key)) {
|
||||
if (-not $policyByWorker.ContainsKey($key)) { $policyByWorker[$key] = Get-PolicyJobId $s $jobIds }
|
||||
if (-not $policyByWorker[$key]) { continue }
|
||||
$key = $policyByWorker[$key]
|
||||
}
|
||||
if (-not $sessionsByJob.ContainsKey($key)) { $sessionsByJob[$key] = New-Object 'System.Collections.Generic.List[object]' }
|
||||
$sessionsByJob[$key].Add($s)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user