688 lines
19 KiB
PowerShell
688 lines
19 KiB
PowerShell
<#
|
|
Monitors Veeam Backup & Replication jobs for Zabbix.
|
|
|
|
Default mode prints one JSON object for a Zabbix Agent 2 UserParameter:
|
|
UserParameter=veeam.scripts.monitor,powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Program Files\Zabbix Agent 2\scripts\Monitor-VeeamJobs.ps1"
|
|
|
|
Sender mode pushes the same metrics with zabbix_sender, useful for Task Scheduler:
|
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Program Files\Zabbix Agent 2\scripts\Monitor-VeeamJobs.ps1" -Mode Sender
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[ValidateSet('Json', 'Sender')]
|
|
[string]$Mode = 'Json',
|
|
|
|
[string]$ScriptDir = $PSScriptRoot,
|
|
[string]$JobExclusionFilterFile,
|
|
|
|
[string]$ZabbixSender = 'C:\Program Files\Zabbix Agent 2\zabbix_sender.exe',
|
|
[string]$ZabbixConfig = 'C:\Program Files\Zabbix Agent 2\zabbix_agent2.conf',
|
|
[string]$ZabbixServer,
|
|
[string]$ZabbixHost
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ScriptDir)) {
|
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($JobExclusionFilterFile)) {
|
|
$JobExclusionFilterFile = Join-Path $ScriptDir 'NotifyOfDisabledJobs_EXCLUSIONS.IN'
|
|
}
|
|
|
|
function Import-VeeamPowerShell {
|
|
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue
|
|
|
|
if (-not (Get-Command Get-VBRJob -ErrorAction SilentlyContinue) -and
|
|
-not (Get-Command Get-VBRComputerBackupJob -ErrorAction SilentlyContinue)) {
|
|
Import-Module Veeam.Backup.PowerShell -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
if (-not (Get-Command Get-VBRJob -ErrorAction SilentlyContinue) -and
|
|
-not (Get-Command Get-VBRComputerBackupJob -ErrorAction SilentlyContinue)) {
|
|
throw 'Veeam PowerShell commands are not available. Run the script on the Veeam server or install/load the Veeam PowerShell module.'
|
|
}
|
|
}
|
|
|
|
function Get-ZabbixAgentConfigValue {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Path,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Name
|
|
)
|
|
|
|
if (-not (Test-Path -Path $Path)) {
|
|
return $null
|
|
}
|
|
|
|
$line = Get-Content -Path $Path |
|
|
Where-Object { $_ -match "^\s*$([regex]::Escape($Name))\s*=" -and $_ -notmatch '^\s*#' } |
|
|
Select-Object -Last 1
|
|
|
|
if (-not $line) {
|
|
return $null
|
|
}
|
|
|
|
return (($line -split '=', 2)[1]).Trim()
|
|
}
|
|
|
|
function Get-ZabbixServerEndpoints {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Servers
|
|
)
|
|
|
|
$endpoints = @()
|
|
|
|
foreach ($serverEndpoint in ($Servers -split ',')) {
|
|
$serverEndpoint = $serverEndpoint.Trim()
|
|
|
|
if ([string]::IsNullOrWhiteSpace($serverEndpoint)) {
|
|
continue
|
|
}
|
|
|
|
$serverHost = $serverEndpoint
|
|
$serverPort = $null
|
|
|
|
if ($serverEndpoint -match '^(?<host>.+):(?<port>\d+)$') {
|
|
$serverHost = $Matches.host
|
|
$serverPort = $Matches.port
|
|
}
|
|
|
|
$endpoints += [pscustomobject]@{
|
|
Host = $serverHost
|
|
Port = $serverPort
|
|
}
|
|
}
|
|
|
|
return $endpoints
|
|
}
|
|
|
|
function Get-ObjectValue {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$InputObject,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string[]]$Paths
|
|
)
|
|
|
|
foreach ($path in $Paths) {
|
|
$current = $InputObject
|
|
|
|
foreach ($part in ($path -split '\.')) {
|
|
if ($null -eq $current) {
|
|
break
|
|
}
|
|
|
|
$property = $current.PSObject.Properties[$part]
|
|
|
|
if ($null -eq $property) {
|
|
$current = $null
|
|
break
|
|
}
|
|
|
|
$current = $property.Value
|
|
}
|
|
|
|
if ($null -ne $current) {
|
|
return $current
|
|
}
|
|
}
|
|
|
|
return $null
|
|
}
|
|
|
|
function Invoke-ObjectMethodValue {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$InputObject,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string[]]$Names
|
|
)
|
|
|
|
foreach ($name in $Names) {
|
|
if ($null -eq $InputObject) {
|
|
return $null
|
|
}
|
|
|
|
$method = $InputObject.PSObject.Methods[$name]
|
|
|
|
if ($null -eq $method) {
|
|
continue
|
|
}
|
|
|
|
try {
|
|
$value = $method.Invoke()
|
|
|
|
if ($null -ne $value) {
|
|
return $value
|
|
}
|
|
}
|
|
catch {
|
|
continue
|
|
}
|
|
}
|
|
|
|
return $null
|
|
}
|
|
|
|
function Get-VeeamJobName {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$Job
|
|
)
|
|
|
|
$name = Get-ObjectValue -InputObject $Job -Paths @('Name', 'Info.Name')
|
|
|
|
if ([string]::IsNullOrWhiteSpace($name)) {
|
|
return '<unknown>'
|
|
}
|
|
|
|
return $name
|
|
}
|
|
|
|
function ConvertTo-ZabbixDateTime {
|
|
param(
|
|
[object]$Value
|
|
)
|
|
|
|
if ($null -eq $Value) {
|
|
return $null
|
|
}
|
|
|
|
if ($Value -is [datetime]) {
|
|
if ($Value -eq [datetime]::MinValue -or $Value -eq [datetime]::MaxValue) {
|
|
return $null
|
|
}
|
|
|
|
return $Value.ToString('yyyy-MM-dd HH:mm:ss')
|
|
}
|
|
|
|
$text = [string]$Value
|
|
|
|
if ([string]::IsNullOrWhiteSpace($text)) {
|
|
return $null
|
|
}
|
|
|
|
return $text
|
|
}
|
|
|
|
function Get-VeeamJobScheduleEnabled {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$Job
|
|
)
|
|
|
|
return Get-ObjectValue -InputObject $Job -Paths @(
|
|
'Info.IsScheduleEnabled',
|
|
'IsScheduleEnabled',
|
|
'ScheduleEnabled',
|
|
'ScheduleOptions.Enabled',
|
|
'JobScheduleOptions.Enabled'
|
|
)
|
|
}
|
|
|
|
function Get-VeeamJobLastSession {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$Job
|
|
)
|
|
|
|
return Invoke-ObjectMethodValue -InputObject $Job -Names @(
|
|
'FindLastSession',
|
|
'GetLastSession',
|
|
'FindLastBackupSession'
|
|
)
|
|
}
|
|
|
|
function Get-VeeamJobLastResult {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$Job,
|
|
|
|
[object]$LastSession
|
|
)
|
|
|
|
$value = Get-ObjectValue -InputObject $Job -Paths @(
|
|
'Info.LastResult',
|
|
'LastResult',
|
|
'Info.LatestRunResult',
|
|
'LatestRunResult'
|
|
)
|
|
|
|
if ($null -ne $value) {
|
|
return $value
|
|
}
|
|
|
|
$value = Invoke-ObjectMethodValue -InputObject $Job -Names @(
|
|
'GetLastResult',
|
|
'FindLastResult'
|
|
)
|
|
|
|
if ($null -ne $value) {
|
|
return $value
|
|
}
|
|
|
|
if ($null -eq $LastSession) {
|
|
return $null
|
|
}
|
|
|
|
return Get-ObjectValue -InputObject $LastSession -Paths @(
|
|
'Result',
|
|
'Info.Result',
|
|
'JobResult',
|
|
'Status'
|
|
)
|
|
}
|
|
|
|
function Get-VeeamJobLastState {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$Job,
|
|
|
|
[object]$LastSession
|
|
)
|
|
|
|
$value = Get-ObjectValue -InputObject $Job -Paths @(
|
|
'Info.LastState',
|
|
'LastState',
|
|
'Info.LatestRunState',
|
|
'LatestRunState'
|
|
)
|
|
|
|
if ($null -ne $value) {
|
|
return $value
|
|
}
|
|
|
|
if ($null -eq $LastSession) {
|
|
return $null
|
|
}
|
|
|
|
return Get-ObjectValue -InputObject $LastSession -Paths @(
|
|
'State',
|
|
'Info.State',
|
|
'Status'
|
|
)
|
|
}
|
|
|
|
function Get-VeeamJobLastRun {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$Job,
|
|
|
|
[object]$LastSession
|
|
)
|
|
|
|
$value = Get-ObjectValue -InputObject $Job -Paths @(
|
|
'Info.LatestRunLocal',
|
|
'LatestRunLocal',
|
|
'Info.LastRunLocal',
|
|
'LastRunLocal',
|
|
'Info.LastRun',
|
|
'LastRun',
|
|
'Info.LastStartTime',
|
|
'LastStartTime',
|
|
'Info.LastEndTime',
|
|
'LastEndTime'
|
|
)
|
|
|
|
if ($null -eq $value -and $null -ne $LastSession) {
|
|
$value = Get-ObjectValue -InputObject $LastSession -Paths @(
|
|
'CreationTime',
|
|
'CreationTimeLocal',
|
|
'EndTime',
|
|
'EndTimeLocal',
|
|
'Info.CreationTime',
|
|
'Info.EndTime'
|
|
)
|
|
}
|
|
|
|
return ConvertTo-ZabbixDateTime -Value $value
|
|
}
|
|
|
|
function Get-VeeamJobNextRun {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$Job
|
|
)
|
|
|
|
$value = Get-ObjectValue -InputObject $Job -Paths @(
|
|
'Info.NextRun',
|
|
'NextRun',
|
|
'ScheduleOptions.NextRun',
|
|
'JobScheduleOptions.NextRun',
|
|
'ScheduleOptions.NextRunLocal',
|
|
'JobScheduleOptions.NextRunLocal'
|
|
)
|
|
|
|
return ConvertTo-ZabbixDateTime -Value $value
|
|
}
|
|
|
|
function Get-VeeamBackupJobName {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object]$Backup
|
|
)
|
|
|
|
return Get-ObjectValue -InputObject $Backup -Paths @(
|
|
'JobName',
|
|
'Info.JobName',
|
|
'Job.Name',
|
|
'Name'
|
|
)
|
|
}
|
|
|
|
function Get-VeeamRestorePointCounts {
|
|
$counts = @{}
|
|
|
|
if (-not (Get-Command Get-VBRBackup -ErrorAction SilentlyContinue) -or
|
|
-not (Get-Command Get-VBRRestorePoint -ErrorAction SilentlyContinue)) {
|
|
return $counts
|
|
}
|
|
|
|
foreach ($backup in @(Get-VBRBackup -WarningAction SilentlyContinue)) {
|
|
$jobName = Get-VeeamBackupJobName -Backup $backup
|
|
|
|
if ([string]::IsNullOrWhiteSpace($jobName)) {
|
|
continue
|
|
}
|
|
|
|
try {
|
|
$restorePointCount = @(Get-VBRRestorePoint -Backup $backup -WarningAction SilentlyContinue).Count
|
|
|
|
if (-not $counts.ContainsKey($jobName)) {
|
|
$counts[$jobName] = 0
|
|
}
|
|
|
|
$counts[$jobName] += $restorePointCount
|
|
}
|
|
catch {
|
|
if (-not $counts.ContainsKey($jobName)) {
|
|
$counts[$jobName] = $null
|
|
}
|
|
}
|
|
}
|
|
|
|
return $counts
|
|
}
|
|
|
|
function Format-ZabbixTextValue {
|
|
param(
|
|
[object[]]$Values
|
|
)
|
|
|
|
$text = @($Values |
|
|
Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
|
|
Sort-Object -Unique) -join '; '
|
|
|
|
if ([string]::IsNullOrWhiteSpace($text)) {
|
|
return '-'
|
|
}
|
|
|
|
return $text
|
|
}
|
|
|
|
function Format-VeeamJobDetailsTable {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[object[]]$JobDetails
|
|
)
|
|
|
|
if ($JobDetails.Count -eq 0) {
|
|
return '-'
|
|
}
|
|
|
|
$lines = @(
|
|
'Name | Enabled | Last run | Next run | Result | Restore points'
|
|
'--- | --- | --- | --- | --- | ---'
|
|
)
|
|
|
|
foreach ($job in ($JobDetails | Sort-Object -Property name)) {
|
|
$enabled = if ($job.enabled -eq $true) { 'yes' } elseif ($job.enabled -eq $false) { 'no' } else { 'unknown' }
|
|
$lastRun = if ([string]::IsNullOrWhiteSpace($job.last_run)) { '-' } else { $job.last_run }
|
|
$nextRun = if ([string]::IsNullOrWhiteSpace($job.next_run)) { '-' } else { $job.next_run }
|
|
$result = if ([string]::IsNullOrWhiteSpace($job.last_result)) { $job.last_state } else { $job.last_result }
|
|
$restorePoints = if ($null -eq $job.restore_points) { '-' } else { $job.restore_points }
|
|
|
|
$lines += ('{0} | {1} | {2} | {3} | {4} | {5}' -f $job.name, $enabled, $lastRun, $nextRun, $result, $restorePoints)
|
|
}
|
|
|
|
return ($lines -join [Environment]::NewLine)
|
|
}
|
|
|
|
function Format-ZabbixSenderValue {
|
|
param(
|
|
[object]$Value
|
|
)
|
|
|
|
if ($null -eq $Value) {
|
|
return '-'
|
|
}
|
|
|
|
$text = [string]$Value
|
|
$text = $text -replace "(`r`n|`n|`r)", ' / '
|
|
|
|
if ([string]::IsNullOrWhiteSpace($text)) {
|
|
return '-'
|
|
}
|
|
|
|
return $text
|
|
}
|
|
|
|
function Get-VeeamJobs {
|
|
Import-VeeamPowerShell
|
|
|
|
$jobs = @()
|
|
|
|
if (Get-Command Get-VBRJob -ErrorAction SilentlyContinue) {
|
|
$jobs += @(Get-VBRJob -WarningAction SilentlyContinue)
|
|
}
|
|
|
|
if (Get-Command Get-VBRComputerBackupJob -ErrorAction SilentlyContinue) {
|
|
$jobs += @(Get-VBRComputerBackupJob -WarningAction SilentlyContinue)
|
|
}
|
|
|
|
return $jobs
|
|
}
|
|
|
|
function Get-VeeamJobMetrics {
|
|
$allJobs = @(Get-VeeamJobs)
|
|
$restorePointCounts = Get-VeeamRestorePointCounts
|
|
$jobDetails = @($allJobs | ForEach-Object {
|
|
$jobName = Get-VeeamJobName -Job $_
|
|
$scheduleEnabled = Get-VeeamJobScheduleEnabled -Job $_
|
|
$lastSession = Get-VeeamJobLastSession -Job $_
|
|
$lastResult = Get-VeeamJobLastResult -Job $_ -LastSession $lastSession
|
|
$lastState = Get-VeeamJobLastState -Job $_ -LastSession $lastSession
|
|
$restorePoints = $null
|
|
|
|
if ($restorePointCounts.ContainsKey($jobName)) {
|
|
$restorePoints = $restorePointCounts[$jobName]
|
|
}
|
|
|
|
[ordered]@{
|
|
name = $jobName
|
|
enabled = $scheduleEnabled
|
|
last_run = Get-VeeamJobLastRun -Job $_ -LastSession $lastSession
|
|
next_run = Get-VeeamJobNextRun -Job $_
|
|
last_result = if ($null -eq $lastResult) { $null } else { [string]$lastResult }
|
|
last_state = if ($null -eq $lastState) { $null } else { [string]$lastState }
|
|
restore_points = $restorePoints
|
|
}
|
|
})
|
|
$disabledJobs = @($allJobs | Where-Object {
|
|
$scheduleEnabled = Get-VeeamJobScheduleEnabled -Job $_
|
|
|
|
$scheduleEnabled -eq $false
|
|
})
|
|
$errorJobs = @($allJobs | Where-Object {
|
|
$lastSession = Get-VeeamJobLastSession -Job $_
|
|
$lastState = Get-VeeamJobLastState -Job $_ -LastSession $lastSession
|
|
$lastResult = Get-VeeamJobLastResult -Job $_ -LastSession $lastSession
|
|
|
|
$lastState -eq 'Failed' -or $lastResult -eq 'Failed'
|
|
})
|
|
$warningJobs = @($allJobs | Where-Object {
|
|
$lastSession = Get-VeeamJobLastSession -Job $_
|
|
$lastState = Get-VeeamJobLastState -Job $_ -LastSession $lastSession
|
|
$lastResult = Get-VeeamJobLastResult -Job $_ -LastSession $lastSession
|
|
|
|
$lastState -eq 'Warning' -or $lastResult -eq 'Warning'
|
|
})
|
|
$successfulJobs = @($jobDetails | Where-Object {
|
|
$_.last_result -in @('Success', 'Succeeded') -or $_.last_state -in @('Success', 'Succeeded')
|
|
})
|
|
|
|
$disabledCount = $disabledJobs.Count
|
|
$disabledExcludedJobs = @()
|
|
|
|
if (Test-Path -Path $JobExclusionFilterFile) {
|
|
$jobsToExclude = @(Get-Content -Path $JobExclusionFilterFile |
|
|
Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
|
|
ForEach-Object { $_.Trim() })
|
|
|
|
if ($jobsToExclude.Count -gt 0) {
|
|
$disabledExcludedJobs = @($disabledJobs | Where-Object {
|
|
$jobName = Get-VeeamJobName -Job $_
|
|
$jobsToExclude | Where-Object { $jobName -like "*$_*" }
|
|
})
|
|
|
|
$disabledJobsFiltered = @($disabledJobs | Where-Object {
|
|
$jobName = Get-VeeamJobName -Job $_
|
|
-not ($jobsToExclude | Where-Object { $jobName -like "*$_*" })
|
|
})
|
|
$disabledJobs = $disabledJobsFiltered
|
|
$disabledCount = $disabledJobsFiltered.Count
|
|
}
|
|
}
|
|
|
|
[ordered]@{
|
|
total = $allJobs.Count
|
|
disabled = $disabledCount
|
|
successful = $successfulJobs.Count
|
|
error = $errorJobs.Count
|
|
warning = $warningJobs.Count
|
|
disabled_names = Format-ZabbixTextValue -Values @($disabledJobs | ForEach-Object { Get-VeeamJobName -Job $_ })
|
|
disabled_excluded_names = Format-ZabbixTextValue -Values @($disabledExcludedJobs | ForEach-Object { Get-VeeamJobName -Job $_ })
|
|
error_names = Format-ZabbixTextValue -Values @($errorJobs | ForEach-Object { Get-VeeamJobName -Job $_ })
|
|
warning_names = Format-ZabbixTextValue -Values @($warningJobs | ForEach-Object { Get-VeeamJobName -Job $_ })
|
|
jobs_table = Format-VeeamJobDetailsTable -JobDetails $jobDetails
|
|
jobs = $jobDetails
|
|
}
|
|
}
|
|
|
|
function Send-ZabbixMetrics {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[System.Collections.IDictionary]$Metrics
|
|
)
|
|
|
|
if (-not (Test-Path -Path $ZabbixSender)) {
|
|
throw "zabbix_sender.exe was not found: $ZabbixSender"
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ZabbixServer)) {
|
|
$ZabbixServer = Get-ZabbixAgentConfigValue -Path $ZabbixConfig -Name 'ServerActive'
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ZabbixServer)) {
|
|
$ZabbixServer = Get-ZabbixAgentConfigValue -Path $ZabbixConfig -Name 'Server'
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ZabbixHost)) {
|
|
$ZabbixHost = Get-ZabbixAgentConfigValue -Path $ZabbixConfig -Name 'Hostname'
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ZabbixHost)) {
|
|
$hostnameItem = Get-ZabbixAgentConfigValue -Path $ZabbixConfig -Name 'HostnameItem'
|
|
|
|
if ([string]::IsNullOrWhiteSpace($hostnameItem) -or $hostnameItem -eq 'system.hostname') {
|
|
$ZabbixHost = $env:COMPUTERNAME
|
|
}
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ZabbixServer)) {
|
|
throw "Zabbix server was not provided and was not found in $ZabbixConfig"
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ZabbixHost)) {
|
|
throw "Zabbix hostname was not provided, was not found in $ZabbixConfig, and COMPUTERNAME is empty. Pass -ZabbixHost with the exact Zabbix host name."
|
|
}
|
|
|
|
$serverEndpoints = @(Get-ZabbixServerEndpoints -Servers $ZabbixServer)
|
|
|
|
if ($serverEndpoints.Count -eq 0) {
|
|
throw "No usable Zabbix server endpoints were found in: $ZabbixServer"
|
|
}
|
|
|
|
$senderInput = New-TemporaryFile
|
|
|
|
try {
|
|
Write-Host "Sending as host: $ZabbixHost"
|
|
|
|
@(
|
|
"`"$ZabbixHost`" veeam.jobs.total $($Metrics.total)"
|
|
"`"$ZabbixHost`" veeam.jobs.disabled $($Metrics.disabled)"
|
|
"`"$ZabbixHost`" veeam.jobs.successful $($Metrics.successful)"
|
|
"`"$ZabbixHost`" veeam.jobs.error $($Metrics.error)"
|
|
"`"$ZabbixHost`" veeam.jobs.warning $($Metrics.warning)"
|
|
"`"$ZabbixHost`" veeam.jobs.disabled.names $(Format-ZabbixSenderValue -Value $Metrics.disabled_names)"
|
|
"`"$ZabbixHost`" veeam.jobs.disabled.excluded.names $(Format-ZabbixSenderValue -Value $Metrics.disabled_excluded_names)"
|
|
"`"$ZabbixHost`" veeam.jobs.error.names $(Format-ZabbixSenderValue -Value $Metrics.error_names)"
|
|
"`"$ZabbixHost`" veeam.jobs.warning.names $(Format-ZabbixSenderValue -Value $Metrics.warning_names)"
|
|
"`"$ZabbixHost`" veeam.jobs.table $(Format-ZabbixSenderValue -Value $Metrics.jobs_table)"
|
|
) | Set-Content -Path $senderInput -Encoding ASCII
|
|
|
|
$failedEndpoints = @()
|
|
|
|
foreach ($serverEndpoint in $serverEndpoints) {
|
|
$senderArgs = @('-z', $serverEndpoint.Host, '-i', $senderInput)
|
|
|
|
if (-not [string]::IsNullOrWhiteSpace($serverEndpoint.Port)) {
|
|
$senderArgs += @('-p', $serverEndpoint.Port)
|
|
}
|
|
|
|
$displayEndpoint = $serverEndpoint.Host
|
|
|
|
if (-not [string]::IsNullOrWhiteSpace($serverEndpoint.Port)) {
|
|
$displayEndpoint = "$displayEndpoint`:$($serverEndpoint.Port)"
|
|
}
|
|
|
|
Write-Host "Sending to Zabbix endpoint: $displayEndpoint"
|
|
& $ZabbixSender @senderArgs
|
|
|
|
if ($LASTEXITCODE -eq 0) {
|
|
return
|
|
}
|
|
|
|
$failedEndpoints += "$displayEndpoint (exit code $LASTEXITCODE)"
|
|
}
|
|
|
|
throw "zabbix_sender failed for all configured endpoints: $($failedEndpoints -join '; ')"
|
|
}
|
|
finally {
|
|
Remove-Item -Path $senderInput -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
|
|
try {
|
|
$metrics = Get-VeeamJobMetrics
|
|
|
|
if ($Mode -eq 'Sender') {
|
|
Send-ZabbixMetrics -Metrics $metrics
|
|
}
|
|
else {
|
|
$metrics | ConvertTo-Json -Depth 5 -Compress
|
|
}
|
|
}
|
|
catch {
|
|
Write-Error $_.Exception.Message
|
|
exit 1
|
|
}
|