200 lines
5.3 KiB
PowerShell
200 lines
5.3 KiB
PowerShell
<#
|
||
.SYNOPSIS
|
||
Milestone XProtect Incident Report Generator
|
||
|
||
.DESCRIPTION
|
||
Analyse les événements Windows liés à Milestone XProtect :
|
||
- Redémarrages serveur
|
||
- Crash Recording Server
|
||
- Crash VideoOS
|
||
- Erreurs disque (Event ID 7)
|
||
|
||
Génère :
|
||
- Synthèse console
|
||
- 3 dernières erreurs significatives
|
||
- Historique complet structuré
|
||
|
||
.PARAMETER Days
|
||
Nombre de jours à analyser (défaut : 4)
|
||
|
||
.AUTHOR
|
||
Sébastien Couratin – Semper Connect
|
||
|
||
.LICENSE
|
||
GNU AGPL-3.0
|
||
#>
|
||
|
||
param(
|
||
[int]$Days = 4,
|
||
[int]$DetailCount = 3
|
||
)
|
||
|
||
|
||
# Encodage UTF8 console
|
||
chcp 65001 > $null
|
||
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||
|
||
$start = (Get-Date).AddDays(-$Days)
|
||
|
||
Write-Verbose "Analyse des $Days derniers jours"
|
||
Write-Verbose "Date de début : $start"
|
||
|
||
# ==========================================================
|
||
# 🔎 RÉCUPÉRATION DES ÉVÉNEMENTS
|
||
# ==========================================================
|
||
|
||
$reboots = Get-WinEvent -FilterHashtable @{
|
||
LogName='System'
|
||
StartTime=$start
|
||
} -ErrorAction SilentlyContinue | Where-Object {
|
||
($_.Id -eq 12 -and $_.ProviderName -eq "Microsoft-Windows-Kernel-General") -or
|
||
($_.Id -eq 41) -or
|
||
($_.Id -eq 1074)
|
||
}
|
||
|
||
$recordingCrash = Get-WinEvent -FilterHashtable @{
|
||
LogName='System'
|
||
Id=7031
|
||
StartTime=$start
|
||
} -ErrorAction SilentlyContinue | Where-Object {
|
||
$_.Message -like "*Recording Server*"
|
||
}
|
||
|
||
$videoOSCrash = Get-WinEvent -FilterHashtable @{
|
||
LogName='Application'
|
||
Id=1000
|
||
StartTime=$start
|
||
} -ErrorAction SilentlyContinue | Where-Object {
|
||
$_.Message -like "*VideoOS*"
|
||
}
|
||
|
||
$diskErrors = Get-WinEvent -FilterHashtable @{
|
||
LogName='System'
|
||
Id=7
|
||
StartTime=$start
|
||
} -ErrorAction SilentlyContinue
|
||
|
||
if (-not $diskErrors) { $diskErrors = @() }
|
||
|
||
# ==========================================================
|
||
# 🧠 CONSTRUCTION HISTORIQUE STRUCTURÉ
|
||
# ==========================================================
|
||
|
||
$allEvents = @()
|
||
|
||
foreach ($evt in $videoOSCrash) {
|
||
$allEvents += [PSCustomObject]@{
|
||
Time = $evt.TimeCreated
|
||
Type = "CRASH VIDEOOS"
|
||
Severity = "CRITICAL"
|
||
Message = $evt.Message
|
||
}
|
||
}
|
||
|
||
foreach ($evt in $recordingCrash) {
|
||
$allEvents += [PSCustomObject]@{
|
||
Time = $evt.TimeCreated
|
||
Type = "CRASH RECORDING"
|
||
Severity = "CRITICAL"
|
||
Message = $evt.Message
|
||
}
|
||
}
|
||
|
||
foreach ($evt in $diskErrors) {
|
||
$allEvents += [PSCustomObject]@{
|
||
Time = $evt.TimeCreated
|
||
Type = "ERREUR DISQUE"
|
||
Severity = "CRITICAL"
|
||
Message = $evt.Message
|
||
}
|
||
}
|
||
|
||
foreach ($evt in $reboots) {
|
||
$allEvents += [PSCustomObject]@{
|
||
Time = $evt.TimeCreated
|
||
Type = "REDÉMARRAGE SERVEUR"
|
||
Severity = "WARNING"
|
||
Message = "EventID $($evt.Id)"
|
||
}
|
||
}
|
||
|
||
$allEvents = $allEvents | Sort-Object Time
|
||
|
||
# ==========================================================
|
||
# 🎯 3 DERNIÈRES ERREURS SIGNIFICATIVES
|
||
# ==========================================================
|
||
|
||
$lastCritical = $allEvents |
|
||
Where-Object {$_.Severity -eq "CRITICAL"} |
|
||
Sort-Object Time -Descending |
|
||
Select-Object -First $DetailCount
|
||
|
||
# ==========================================================
|
||
# 📊 SYNTHÈSE CONSOLE
|
||
# ==========================================================
|
||
|
||
Write-Host ""
|
||
Write-Host "==============================================="
|
||
Write-Host " SYNTHÈSE INCIDENTS MILESTONE XPROTECT"
|
||
Write-Host "==============================================="
|
||
Write-Host "Période analysée : $Days jours"
|
||
Write-Host ""
|
||
|
||
Write-Host "Redémarrages serveur :" $reboots.Count
|
||
Write-Host "Crash Recording Server :" $recordingCrash.Count
|
||
Write-Host "Crash Application VideoOS :" $videoOSCrash.Count
|
||
Write-Host "Erreurs disque (ID 7) :" $diskErrors.Count
|
||
Write-Host ""
|
||
|
||
if ($lastCritical.Count -gt 0) {
|
||
Write-Host "$DetailCount dernières erreurs significatives :"
|
||
$lastCritical | Format-Table Time, Type -AutoSize
|
||
}
|
||
|
||
# ==========================================================
|
||
# 🧾 GÉNÉRATION RAPPORT
|
||
# ==========================================================
|
||
|
||
$reportDir = Join-Path $PSScriptRoot "..\reports"
|
||
|
||
if (-not (Test-Path $reportDir)) {
|
||
New-Item -ItemType Directory -Path $reportDir | Out-Null
|
||
}
|
||
|
||
$reportPath = Join-Path $reportDir ("Milestone_Report_{0}.txt" -f (Get-Date -Format 'yyyyMMdd_HHmm'))
|
||
|
||
$report = @()
|
||
$report += "==============================================="
|
||
$report += "RAPPORT INCIDENTS MILESTONE XPROTECT"
|
||
$report += "==============================================="
|
||
$report += "Date génération : $(Get-Date)"
|
||
$report += "Période analysée : $Days jours"
|
||
$report += ""
|
||
$report += "Redémarrages serveur : $($reboots.Count)"
|
||
$report += "Crash Recording Server : $($recordingCrash.Count)"
|
||
$report += "Crash Application VideoOS : $($videoOSCrash.Count)"
|
||
$report += "Erreurs disque (ID 7) : $($diskErrors.Count)"
|
||
$report += ""
|
||
|
||
$report += "==== $DetailCount DERNIÈRES ERREURS SIGNIFICATIVES ===="
|
||
|
||
foreach ($err in $lastCritical) {
|
||
$report += "--------------------------------"
|
||
$report += "Date : $($err.Time)"
|
||
$report += "Type : $($err.Type)"
|
||
$report += "Message : $($err.Message)"
|
||
}
|
||
|
||
$report += ""
|
||
$report += "==== HISTORIQUE COMPLET STRUCTURÉ ===="
|
||
|
||
foreach ($evt in $allEvents) {
|
||
$report += "$($evt.Time) | $($evt.Type) | $($evt.Severity)"
|
||
}
|
||
|
||
$report | Out-File -FilePath $reportPath -Encoding UTF8
|
||
|
||
Write-Host ""
|
||
Write-Host "Rapport généré :" $reportPath
|
||
Write-Host ""
|