diff --git a/Acronis/Acronis_monitoring.ps1 b/Acronis/Acronis_monitoring.ps1 new file mode 100644 index 0000000..32fa3c7 --- /dev/null +++ b/Acronis/Acronis_monitoring.ps1 @@ -0,0 +1,145 @@ +<# +.SYNOPSIS + Acronis Universal Monitor — ОДИН скрипт для всех +.DESCRIPTION + Авто-обнаружение задач, отправка агрегированных данных в Zabbix. + Работает с универсальным шаблоном на всех клиентах. +#> + +# ==================== ЗАГРУЗКА КОНФИГА ==================== +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ConfigFile = Join-Path $ScriptDir "config.json" + +if (-not (Test-Path $ConfigFile)) { + Write-Error "Конфиг не найден: $ConfigFile" + exit 1 +} + +$Config = Get-Content $ConfigFile -Raw -Encoding UTF8 | ConvertFrom-Json + +$Z_SENDER = $Config.zabbix_sender +$Z_SERVER = $Config.zabbix_server +$Z_HOST = $Config.zabbix_host +$Z_TLS_ID = $Config.psk_identity +$Z_TLS_KEY = $Config.psk_key_file +$LOG_PATH = $Config.acronis_log_path +$SCAN_DAYS = $Config.scan_days +$MAX_AGE = $Config.max_age_seconds +# =========================================================== + +function Send-ToZabbix { + param([string]$Key, [int]$Value) + + $params = @( + '-z', $Z_SERVER, '-s', $Z_HOST, '-k', $Key, '-o', $Value.ToString(), + '--tls-connect', 'psk', '--tls-psk-identity', $Z_TLS_ID, '--tls-psk-file', $Z_TLS_KEY + ) + + $result = & $Z_SENDER @params 2>&1 + return -not ($result -match 'failed: [1-9]') +} + +function Parse-AcronisTime { + param([string]$Line) + if ($Line -match '^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}):(\d{3})([\+\-]\d{2}:\d{2})') { + $isoString = "$($matches[1]).$($matches[2])$($matches[3])" + try { return [datetime]::Parse($isoString) } catch { return $null } + } + return $null +} + +function Get-AllTaskUUIDs { + param([string]$LogPath, [int]$Days) + $dateLimit = (Get-Date).AddDays(-$Days) + $uuids = @{} + + Get-ChildItem -Path $LogPath -Filter "*.log" -File | + Where-Object { $_.LastWriteTime -gt $dateLimit } | + ForEach-Object { + if ($_.Name -match 'ti_demon_([0-9A-F-]{36})_') { + $uuids[$matches[1].ToUpper()] = $true + } + } + + return $uuids.Keys +} + +function Get-TaskStatus { + param([string]$LogPath, [string]$TaskUUID) + + $logFile = Get-ChildItem -Path $LogPath -Filter "*$TaskUUID*.log" -File | + Sort-Object LastWriteTime -Descending | Select-Object -First 1 + + if (-not $logFile) { return @{ Status = 1; Age = $MAX_AGE; Time = $null } } + + try { + $content = Get-Content -Path $logFile.FullName -Raw -Encoding UTF8 + $successLine = $content | Select-String 'Операция завершена успешно' | Select-Object -First 1 + + if ($successLine) { + $time = Parse-AcronisTime -Line $successLine.Line + $age = if ($time) { [math]::Round(((Get-Date) - $time).TotalSeconds) } else { $MAX_AGE } + if ($age -lt 0) { $age = 0 } + return @{ Status = 0; Age = $age; Time = $time } + } else { + return @{ Status = 1; Age = $MAX_AGE; Time = $null } + } + } catch { + return @{ Status = 1; Age = $MAX_AGE; Time = $null } + } +} + +# ==================== ОСНОВНАЯ ЛОГИКА ==================== + +Write-Host "╔════════════════════════════════════════════╗" -ForegroundColor Cyan +Write-Host "║ Acronis Monitor — Universal ║" -ForegroundColor Cyan +Write-Host "╚════════════════════════════════════════════╝" -ForegroundColor Cyan +Write-Host "Server: $Z_SERVER | Host: $Z_HOST | $(Get-Date)" +Write-Host "" + +if (-not (Test-Path $LOG_PATH)) { + Write-Error "Путь к логам не найден: $LOG_PATH" + Send-ToZabbix -Key "acronis.status[all]" -Value 1 + Send-ToZabbix -Key "acronis.age[oldest]" -Value $MAX_AGE + exit 1 +} + +$taskUUIDs = Get-AllTaskUUIDs -LogPath $LOG_PATH -Days $SCAN_DAYS + +if ($taskUUIDs.Count -eq 0) { + Write-Warning "Задачи не найдены за $SCAN_DAYS дней!" + Send-ToZabbix -Key "acronis.status[all]" -Value 1 + Send-ToZabbix -Key "acronis.age[oldest]" -Value $MAX_AGE + exit 1 +} + +Write-Host "✅ Задач обнаружено: $($taskUUIDs.Count)" +Write-Host "" + +$oldestAge = 0 +$overallStatus = 0 + +foreach ($uuid in $taskUUIDs) { + $task = Get-TaskStatus -LogPath $LOG_PATH -TaskUUID $uuid + + Write-Host " $(if($task.Status -eq 0){'✓'}else{'✗'}) ($([math]::Round($task.Age/3600,1))ч)" -ForegroundColor $(if($task.Status -eq 0){'Green'}else{'Red'}) + + if ($task.Status -ne 0) { $overallStatus = 1 } + if ($task.Age -gt $oldestAge) { $oldestAge = $task.Age } +} + +Write-Host "" +Write-Host "📤 Отправка в Zabbix..." -ForegroundColor Cyan + +$statusSent = Send-ToZabbix -Key "acronis.status[all]" -Value $overallStatus +$ageSent = Send-ToZabbix -Key "acronis.age[oldest]" -Value $oldestAge + +Write-Host " acronis.status[all] = $overallStatus $(if($statusSent){'✓'}else{'✗'})" -ForegroundColor $(if($overallStatus -eq 0){'Green'}else{'Red'}) +Write-Host " acronis.age[oldest] = $oldestAge сек ($([math]::Round($oldestAge/3600,2)) ч) $(if($ageSent){'✓'}else{'✗'})" -ForegroundColor Gray + +if ($statusSent -and $ageSent) { + Write-Host "✅ Все данные отправлены" -ForegroundColor Green +} else { + Write-Host "⚠️ Ошибка отправки" -ForegroundColor Yellow + exit 1 +} \ No newline at end of file diff --git a/Acronis/config.json b/Acronis/config.json new file mode 100644 index 0000000..f3dd823 --- /dev/null +++ b/Acronis/config.json @@ -0,0 +1,11 @@ +{ + "zabbix_server": "92.242.18.210", + "zabbix_host": "EVROTEK_SERVERAPP", + "psk_identity": "EVROTEK_SERVERAPP", + "psk_key_file": "C:\\Program Files\\Zabbix Agent\\psk.key", + "zabbix_sender": "C:\\Program Files\\Zabbix Agent\\zabbix_sender.exe", + "acronis_log_path": "C:\\ProgramData\\Acronis\\TrueImageHome\\Logs\\ti_demon", + "scan_days": 7, + "max_age_seconds": 259200, + "debug": false +} \ No newline at end of file diff --git a/Acronis/monitor.bat b/Acronis/monitor.bat new file mode 100644 index 0000000..a7c1192 --- /dev/null +++ b/Acronis/monitor.bat @@ -0,0 +1,3 @@ +@echo off +chcp 65001 >nul +powershell -ExecutionPolicy Bypass -File "C:\cmd\Acronis\Acronis_Monitor.ps1" >> "C:\cmd\Acronis\monitor.log" 2>&1 \ No newline at end of file