PowerShell script for servers using Windows Server Backup, run hourly as a SYSTEM scheduled task under Windows PowerShell 5.1. Each server is one dashboard job. - Backup jobs from Get-WBJob (in progress and -Previous) within the lookback window; restores are ignored. WSB jobs have no ID, so runs are keyed on start time, which also merges a Running report with the finished one - Error HRESULT -> failed; detailed error or a failed item -> warning; messages include the error description, codes as 0x8XXXXXXX, failed items and the failure log path - Next run from Get-WBSummary's NextBackupTime - Get-WsbCollectorDiagnostics.ps1 dumps the cmdlets' real objects and recent Microsoft-Windows-Backup events (to check whether job times are local or UTC); installer adapted from the MARS one Not yet run against a real server. Co-Authored-By: Claude Opus 5.5 <[email protected]>
62 lines
3.3 KiB
PowerShell
62 lines
3.3 KiB
PowerShell
# Stand-ins for the WindowsServerBackup cmdlets. Object shapes are best guesses until checked
|
|
# against Get-WsbCollectorDiagnostics.ps1 output from a real server.
|
|
#
|
|
# . ./tests/MockWsb.ps1 # nothing running
|
|
# . ./tests/MockWsb.ps1 -WithRunningJob # a backup in progress
|
|
# ./Send-WsbBackupStatus.ps1 -ConfigPath ./my-test-config.json -DryRun
|
|
param([switch]$WithRunningJob)
|
|
|
|
# Fixed to the top of the hour so repeated runs see the same jobs
|
|
$now = Get-Date -Minute 0 -Second 0 -Millisecond 0
|
|
|
|
function New-MockItem($Name, [int]$HResult = 0, $ErrorDescription = '') {
|
|
[pscustomobject]@{ Name = $Name; Type = 'Volume'; State = $(if ($HResult) { 'Failed' } else { 'Completed' })
|
|
HResult = $HResult; ErrorDescription = $ErrorDescription }
|
|
}
|
|
|
|
function New-MockJob($Type, $Start, $End, $State, [int]$HResult = 0, [int]$DetailedHResult = 0, $ErrorDescription = '', $Items = @()) {
|
|
[pscustomobject]@{
|
|
JobType = $Type
|
|
StartTime = $Start
|
|
EndTime = $(if ($End) { $End } else { [datetime]::MinValue })
|
|
JobState = $State
|
|
HResult = $HResult
|
|
DetailedHResult = $DetailedHResult
|
|
ErrorDescription = $ErrorDescription
|
|
JobItems = $Items
|
|
VersionId = $(if ($End) { $Start.ToUniversalTime().ToString('MM/dd/yyyy-HH:mm') } else { '' })
|
|
SuccessLogPath = 'C:\Windows\Logs\WindowsServerBackup\Backup-success.log'
|
|
FailureLogPath = $(if ($HResult -or $DetailedHResult) { 'C:\Windows\Logs\WindowsServerBackup\Backup_Error.log' } else { '' })
|
|
}
|
|
}
|
|
|
|
$global:MockWsbRunning = if ($WithRunningJob) {
|
|
@(New-MockJob 'Backup' $now.AddMinutes(-10) $null 'Running' -Items @((New-MockItem 'C:'), (New-MockItem 'D:')))
|
|
} else {
|
|
# What an idle server might return: an empty job rather than nothing
|
|
@([pscustomobject]@{ JobType = 'None'; StartTime = [datetime]::MinValue; EndTime = [datetime]::MinValue; JobState = 'Unknown' })
|
|
}
|
|
|
|
$global:MockWsbPrevious = @(
|
|
(New-MockJob 'Backup' $now.AddHours(-12) $now.AddHours(-11) 'Completed' -Items @((New-MockItem 'C:'), (New-MockItem 'D:'))),
|
|
# Completed overall, but one volume failed
|
|
(New-MockJob 'Backup' $now.AddHours(-36) $now.AddHours(-35) 'Completed' 0 -2147024891 '' @(
|
|
(New-MockItem 'C:'), (New-MockItem 'D:' -2147024891 'Access is denied.'))),
|
|
# Failed outright: backup target not found (0x80042302)
|
|
(New-MockJob 'Backup' $now.AddHours(-30) $now.AddHours(-29.9) 'Completed' -2147212542 0 `
|
|
'The backup storage location could not be found.'),
|
|
(New-MockJob 'Recovery' $now.AddHours(-5) $now.AddHours(-4) 'Completed'), # a restore: must be ignored
|
|
(New-MockJob 'Backup' $now.AddDays(-5) $now.AddDays(-5).AddHours(1) 'Completed') # outside 48h lookback
|
|
)
|
|
|
|
$global:MockWsbSummary = [pscustomobject]@{
|
|
NextBackupTime = $now.Date.AddHours(21).AddDays($(if ($now.Hour -ge 21) { 1 } else { 0 }))
|
|
LastSuccessfulBackupTime = $now.AddHours(-11)
|
|
LastBackupResultHR = 0
|
|
}
|
|
|
|
function Get-WBJob { param([int]$Previous) if ($PSBoundParameters.ContainsKey('Previous')) { $global:MockWsbPrevious } else { $global:MockWsbRunning } }
|
|
function Get-WBSummary { $global:MockWsbSummary }
|
|
function Get-WBPolicy { [pscustomobject]@{ PolicyName = 'Scheduled' } }
|
|
function Get-WBSchedule { param($Policy) @($global:MockWsbSummary.NextBackupTime) }
|