Raport zilnic automat de sănătate a serverelor generat cu AI – interpretare Event Log și trimitere pe email

Configurare noua (How To)

Situatie

Verificarea zilnică a Event Viewer pe mai multe servere este consumatoare de timp, iar codurile de eroare Windows sunt greu de interpretat rapid. Multe probleme sunt observate abia după ce devin incidente.

Această soluție colectează evenimentele critice și de eroare din ultimele 24 de ore de pe mai multe servere, le trimite unui model AI local care le explică în limbaj uman (ce înseamnă eroarea, ce ar trebui verificat, cât de urgentă e), grupează problemele similare și trimite un raport HTML pe email — automat, în fiecare dimineață.

Backup

Soluția este read-only asupra Event Log-urilor. Necesită doar drepturi de citire remote. Nu modifică nicio configurație de server.

Solutie

Pasi de urmat

Pasul 1 — Pregătire și verificare acces remote la Event Log

powershell
# Lista serverelor de monitorizat
$Servers = @("SRV-DC01", "SRV-FILE01", "SRV-SQL01", "SRV-APP01")

# Verifica accesul la Event Log pe fiecare server
foreach ($Server in $Servers) {
    try {
        Get-WinEvent -ComputerName $Server -LogName System -MaxEvents 1 -ErrorAction Stop | Out-Null
        Write-Host "[OK] $Server - acces confirmat" -ForegroundColor Green
    }
    catch {
        Write-Host "[EROARE] $Server - $_" -ForegroundColor Red
    }
}

Pasul 2 — Funcție de colectare evenimente critice

powershell
function Get-CriticalEvents {
    param(
        [string]$ComputerName,
        [int]$Hours = 24
    )

    $StartTime = (Get-Date).AddHours(-$Hours)

    try {
        $Events = Get-WinEvent -ComputerName $ComputerName -FilterHashtable @{
            LogName   = 'System', 'Application'
            Level     = 1, 2       # 1 = Critical, 2 = Error
            StartTime = $StartTime
        } -ErrorAction Stop -MaxEvents 100

        return $Events | Select-Object `
            @{N='Server';   E={$ComputerName}},
            @{N='Time';     E={$_.TimeCreated}},
            @{N='Level';    E={$_.LevelDisplayName}},
            @{N='EventID';  E={$_.Id}},
            @{N='Source';   E={$_.ProviderName}},
            @{N='Message';  E={($_.Message -split "`n")[0]}}
    }
    catch {
        Write-Warning "Nu s-au putut extrage evenimente de pe $ComputerName : $_"
        return @()
    }
}

Pasul 3 — Funcție de interpretare AI

powershell
function Get-AIHealthAnalysis {
    param(
        [array]$Events,
        [string]$Model = "llama3"
    )

    # Grupeaza evenimentele pentru a reduce volumul trimis
    $Summary = $Events | Group-Object Server, EventID, Source |
        ForEach-Object {
            $first = $_.Group[0]
            "[$($first.Server)] EventID $($first.EventID) | $($first.Source) | " +
            "apariti: $($_.Count) | $($first.Message)"
        }

    $EventsText = $Summary -join "`n"

    $Prompt = @"
Esti un administrator de sistem Windows Server senior.
Analizeaza evenimentele critice si de eroare de mai jos, colectate din ultimele 24 ore.

Pentru fiecare problema semnificativa, raspunde in formatul:

PROBLEMA: <descriere in limbaj uman, ce inseamna eroarea>
SERVER: <serverul/serverele afectate>
URGENTA: <Critica/Ridicata/Medie/Informativa>
CAUZA_PROBABILA: <cea mai probabila cauza>
VERIFICARI: <ce ar trebui verificat concret>

Grupeaza erorile similare. Prioritizeaza in raspuns problemele urgente.
Ignora zgomotul de rutina (ex. erori tranzitorii de retea izolate).
Raspunde DOAR in limba romana, concis si tehnic.

EVENIMENTE:
$EventsText
"@

    $Body = @{
        model  = $Model
        prompt = $Prompt
        stream = $false
    } | ConvertTo-Json -Depth 3

    try {
        $Response = Invoke-RestMethod `
            -Uri "http://localhost:11434/api/generate" `
            -Method POST -ContentType "application/json" `
            -Body $Body -TimeoutSec 180

        return $Response.response
    }
    catch {
        return "EROARE la analiza AI: $_"
    }
}

Pasul 4 — Generare raport HTML

powershell
function New-HealthReportHTML {
    param(
        [string]$Analysis,
        [array]$Events,
        [array]$Servers
    )

    $Date = Get-Date -Format "dd.MM.yyyy HH:mm"
    $AnalysisHTML = $Analysis -replace "`n", "<br/>"

    $EventCount  = $Events.Count
    $ServerStats = $Events | Group-Object Server |
        ForEach-Object { "<li><b>$($_.Name)</b>: $($_.Count) evenimente</li>" }

    return @"
<html>
<head><meta charset="UTF-8"><style>
body { font-family: Segoe UI, Arial, sans-serif; font-size: 14px; color: #333; }
h2 { color: #1a5490; border-bottom: 2px solid #1a5490; padding-bottom: 5px; }
.summary { background: #f4f6f8; padding: 12px; border-left: 4px solid #1a5490; }
.analysis { background: #fff; padding: 12px; border: 1px solid #ddd; margin-top: 15px; }
</style></head>
<body>
<h2>Raport zilnic sanatate servere - $Date</h2>

<div class="summary">
  <b>Servere monitorizate:</b> $($Servers -join ", ")<br/>
  <b>Total evenimente critice/eroare (24h):</b> $EventCount
  <ul>$($ServerStats -join "")</ul>
</div>

<div class="analysis">
  <h3>Analiza AI</h3>
  $AnalysisHTML
</div>

<p style="color:#888;font-size:12px;margin-top:20px;">
Raport generat automat cu model AI local. Verdictele sunt orientative
si necesita confirmare de catre administrator.
</p>
</body></html>
"@
}

Pasul 5 — Script principal

powershell
# ============================================================
# AI Server Health Report
# Autor: Claudiu Ceausescu
# ============================================================

$Servers    = @("SRV-DC01", "SRV-FILE01", "SRV-SQL01", "SRV-APP01")
$ReportPath = "C:\HealthReports"
$Model      = "llama3"

# Setari email
$SmtpServer = "smtp.companie.local"
$MailFrom   = "monitorizare@companie.ro"
$MailTo     = "it-team@companie.ro"

New-Item -ItemType Directory -Force -Path $ReportPath | Out-Null

# Verifica Ollama
try {
    Invoke-RestMethod -Uri "http://localhost:11434/api/tags" -TimeoutSec 5 | Out-Null
    Write-Host "[OK] Ollama activ." -ForegroundColor Green
}
catch {
    Write-Host "[EROARE] Ollama nu raspunde." -ForegroundColor Red
    exit 1
}

# Colectare evenimente de pe toate serverele
$AllEvents = @()
foreach ($Server in $Servers) {
    Write-Host "Colectez evenimente de pe $Server..." -ForegroundColor Cyan
    $AllEvents += Get-CriticalEvents -ComputerName $Server -Hours 24
}

if ($AllEvents.Count -eq 0) {
    Write-Host "Nu exista evenimente critice in ultimele 24 ore." -ForegroundColor Green
    $Analysis = "Nu s-au inregistrat evenimente critice sau de eroare in ultimele 24 de ore pe serverele monitorizate."
}
else {
    Write-Host "Gasit $($AllEvents.Count) evenimente. Trimit spre analiza AI..." -ForegroundColor Cyan
    $Analysis = Get-AIHealthAnalysis -Events $AllEvents -Model $Model
}

# Generare si salvare raport
$HTML       = New-HealthReportHTML -Analysis $Analysis -Events $AllEvents -Servers $Servers
$ReportFile = Join-Path $ReportPath "Health_$(Get-Date -Format 'yyyy-MM-dd').html"
$HTML | Out-File -FilePath $ReportFile -Encoding UTF8

Write-Host "[OK] Raport salvat: $ReportFile" -ForegroundColor Green

# Trimitere pe email
try {
    Send-MailMessage -SmtpServer $SmtpServer -From $MailFrom -To $MailTo `
        -Subject "Raport sanatate servere - $(Get-Date -Format 'dd.MM.yyyy')" `
        -Body $HTML -BodyAsHtml -Encoding UTF8
    Write-Host "[OK] Raport trimis pe email." -ForegroundColor Green
}
catch {
    Write-Host "[EROARE] Trimitere email eșuata: $_" -ForegroundColor Red
}

Pasul 6 — Programare rulare zilnică

powershell
$Action  = New-ScheduledTaskAction -Execute "powershell.exe" `
           -Argument "-ExecutionPolicy Bypass -File C:\Scripts\AI_Health_Report.ps1"
$Trigger = New-ScheduledTaskTrigger -Daily -At "07:00"

Register-ScheduledTask -TaskName "AI_ServerHealthReport" `
    -Action $Action -Trigger $Trigger -RunLevel Highest `
    -Description "Raport zilnic de sanatate servere generat cu AI local"

# Testeaza task-ul imediat
Start-ScheduledTask -TaskName "AI_ServerHealthReport"

Exemplu secțiune din raport:

PROBLEMA: Serviciul de replicare Active Directory nu a reusit sa
sincronizeze cu un partener de replicare
SERVER: SRV-DC01
URGENTA: Ridicata
CAUZA_PROBABILA: Probleme de conectivitate de retea sau DNS catre
controllerul partener
VERIFICARI: Ruleaza repadmin /showrepl, verifica rezolvarea DNS a
numelui partenerului, testeaza porturile RPC (135, 49152-65535)

Tip solutie

Permanent

Voteaza

(12 din 23 persoane apreciaza acest articol)

Despre Autor

Leave A Comment?