522 lines
21 KiB
PowerShell
522 lines
21 KiB
PowerShell
# Script d'Audit Firewall - Network Reputation Service
|
|
# Auteur: Hubert Cornet
|
|
# Date: 03/09/2025
|
|
# Version: 1.0
|
|
|
|
Clear-Host
|
|
|
|
# Configuration globale
|
|
$ErrorActionPreference = "Continue"
|
|
$WarningPreference = "SilentlyContinue"
|
|
|
|
### Functions ###
|
|
|
|
## Function Write-ColorOutput
|
|
Function Write-ColorOutput {
|
|
Param(
|
|
[string]$Text,
|
|
[string]$Color = "White"
|
|
)
|
|
|
|
Try {
|
|
Write-Host $Text -ForegroundColor $Color
|
|
}
|
|
Catch {
|
|
Write-Host $Text
|
|
}
|
|
}
|
|
|
|
## Function Prerequisites
|
|
Function Prerequisites {
|
|
Write-ColorOutput "`n=== Vérification des prérequis ===" "Cyan"
|
|
|
|
# Vérification du fichier JSON
|
|
$JsonFile = Join-Path $PSScriptRoot "file-nrs.json"
|
|
|
|
If(-not (Test-Path $JsonFile)) {
|
|
Write-ColorOutput "ERREUR: Le fichier 'file-nrs.json' n'existe pas!" "Red"
|
|
Write-ColorOutput "Veuillez télécharger ou créer le fichier depuis:" "Yellow"
|
|
Write-ColorOutput "https://github.com/your-repo/file-nrs.json" "Blue"
|
|
Write-ColorOutput "Le fichier doit être placé dans le même dossier que ce script." "Yellow"
|
|
|
|
Return $false
|
|
}
|
|
|
|
Write-ColorOutput "✓ Fichier 'file-nrs.json' trouvé" "Green"
|
|
|
|
# Vérification/Installation des modules requis
|
|
$RequiredModules = @('PSWriteHTML', 'PSWriteColor')
|
|
|
|
Foreach ($Module in $RequiredModules) {
|
|
If(-not (Get-Module -ListAvailable -Name $Module)) {
|
|
Write-ColorOutput "Installation du module $Module..." "Yellow"
|
|
|
|
Try {
|
|
Install-Module -Name $Module -Force -Scope CurrentUser -AllowClobber
|
|
|
|
Write-ColorOutput "✓ Module $Module installé" "Green"
|
|
}
|
|
Catch {
|
|
Write-ColorOutput "ERREUR: Impossible d'installer le module $Module : $($_.Exception.Message)" "Red"
|
|
|
|
Return $false
|
|
}
|
|
}
|
|
Else {
|
|
Write-ColorOutput "✓ Module $Module disponible" "Green"
|
|
}
|
|
|
|
Import-Module $Module -Force
|
|
}
|
|
|
|
return $true
|
|
}
|
|
|
|
## Function Check-Categories
|
|
Function Check-Categories {
|
|
Param(
|
|
[array]$Categories,
|
|
[string]$ProxyUrl = "",
|
|
[System.Management.Automation.PSCredential]$ProxyCredential = $null,
|
|
[int]$TimeoutSeconds = 10
|
|
)
|
|
|
|
$AllResults = @()
|
|
$CategoryCount = 0
|
|
|
|
$BlockKeywors = @("site bloqué", "access denied", "filtrage web", "Access Denied", "Site Blocked") # Définir les mots-clés des page des blocage
|
|
|
|
Foreach ($Category in $Categories.Categorie) {
|
|
$CategoryCount++
|
|
|
|
Show-ProgressBar -Current $CategoryCount -Total $Categories.Categorie.Count -Activity "Test des catégories" -Status "Catégorie: $($category.Categorie.nom)"
|
|
|
|
Write-ColorOutput "`n=== Test de la catégorie: $($Category.nom) ===" "Cyan"
|
|
#Write-ColorOutput "Description: $($category.description)" "Gray"
|
|
|
|
$CategoryResults = @()
|
|
$UrlCount = 0
|
|
|
|
Foreach ($UrlObj in $Category.urls) {
|
|
$UrlCount++
|
|
|
|
Show-ProgressBar -Current $UrlCount -Total $Category.urls.Count -Activity "Test des URLs de '$($Category.nom)'" -Status $UrlObj.url
|
|
|
|
Write-ColorOutput "Test de: $($UrlObj.url)" "Yellow"
|
|
|
|
#$Result = Get-UrlStatus -Url $UrlObj.url -ProxyUrl $ProxyUrl -ProxyCredential $ProxyCredential -TimeoutSeconds $TimeoutSeconds -BlockPageKeywords $BlockPageKeywords
|
|
|
|
$Result = Get-UrlStatus $UrlObj.url $UrlObj.expected_action $BlockPageKeywords
|
|
|
|
$TestResult = [PSCustomObject]@{
|
|
Category = $category.nom
|
|
CategoryId = $category.id
|
|
Url = $urlObj.url
|
|
Reputation = $urlObj.reputation
|
|
ExpectedAction = $urlObj.expected_action
|
|
Status = $result.ActualResult
|
|
StatusCode = $result.StatusCode
|
|
ResponseTime = $result.ResponseTime
|
|
Error = $result.Details
|
|
Score = $result.Score
|
|
IsCorrect = (($TestResult.Status -eq "Bloqué" -and $UrlObj.expected_action -eq "block") -or ($TestResult.Status -eq "Autorisé" -and $UrlObj.expected_action -eq "allow"))
|
|
}
|
|
|
|
$StatusColor = If($testResult.IsCorrect) { "Green" } Else { "Red" }
|
|
Write-ColorOutput " → Résultat: $($TestResult.Status) | Attendu: $($TestResult.ExpectedAction) | Correct: $($TestResult.IsCorrect)" $statusColor
|
|
|
|
$categoryResults += $testResult
|
|
$allResults += $testResult
|
|
}
|
|
|
|
$CategoryScore = Calculate-CategoryScore -Results $categoryResults
|
|
$CategoryGrade = Convert-ScoreToGrade -Score $categoryScore
|
|
|
|
Write-ColorOutput "Score de la catégorie '$($Category.nom)': $categoryScore% (Note: $CategoryGrade)" "Magenta"
|
|
}
|
|
|
|
Write-Progress -Activity "Test des catégories" -Completed
|
|
Write-Progress -Activity "Test des URLs" -Completed
|
|
|
|
return $allResults
|
|
}
|
|
|
|
## Function Show-ProgressBar
|
|
Function Show-ProgressBar {
|
|
Param(
|
|
[int]$Current,
|
|
[int]$Total,
|
|
[string]$Activity,
|
|
[string]$Status = ""
|
|
)
|
|
|
|
$Percent = [math]::Round(($Current / $Total) * 100, 1)
|
|
|
|
Write-Progress -Activity $Activity -Status "$Status ($Current/$Total)" -PercentComplete $Percent
|
|
}
|
|
|
|
## FunctionCalculate-CategoryScore
|
|
Function Calculate-CategoryScore {
|
|
Param(
|
|
[array]$Results
|
|
)
|
|
|
|
$TotalUrls = $Results.Count
|
|
$CorrectResults = 0
|
|
|
|
Foreach ($Result in $Results) {
|
|
$IsBlocked = $Result.Status -eq "Bloqué"
|
|
$ShouldBeBlocked = $result.ExpectedAction -eq "block"
|
|
|
|
If(($IsBlocked -and $ShouldBeBlocked) -or (-not $IsBlocked -and -not $ShouldBeBlocked)) {
|
|
$CorrectResults++
|
|
}
|
|
}
|
|
|
|
If($TotalUrls -eq 0) {
|
|
Return 0
|
|
}
|
|
|
|
Return [math]::Round(($CorrectResults / $TotalUrls) * 100, 2)
|
|
}
|
|
|
|
## Function Convert-ScoreToGrade
|
|
Function Convert-ScoreToGrade {
|
|
Param([double]$Score)
|
|
|
|
switch ($Score) {
|
|
{$_ -ge 95} { return 'A+' }
|
|
{$_ -ge 90} { return 'A' }
|
|
{$_ -ge 85} { return 'B+' }
|
|
{$_ -ge 80} { return 'B' }
|
|
{$_ -ge 75} { return 'C+' }
|
|
{$_ -ge 70} { return 'C' }
|
|
{$_ -ge 65} { return 'D+' }
|
|
{$_ -ge 60} { return 'D' }
|
|
{$_ -ge 55} { return 'E+' }
|
|
{$_ -ge 50} { return 'E' }
|
|
{$_ -ge 45} { return 'F+' }
|
|
default { return 'F' }
|
|
}
|
|
}
|
|
|
|
## Function Get-UrlStatus
|
|
Function Get-UrlStatus {
|
|
Param(
|
|
[string]$Url,
|
|
[string]$ExpectedAction, # 'allow' ou 'block'
|
|
[string[]]$BlockPageKeywords, # Exemple: @("Access Denied", "Site Blocked")
|
|
[string]$ProxyAddress = $null,
|
|
[string]$ProxyUseAuthentication = $null,
|
|
[int]$Timeout = 10
|
|
)
|
|
|
|
$Result = [PSCustomObject]@{
|
|
Url = $Url
|
|
Expected = $ExpectedAction
|
|
ActualResult = "Indéterminé" # Ce qui s'est réellement passé (Bloqué/Autorisé)
|
|
TestStatus = "Échec" # Le statut du test (Conforme/Non Conforme)
|
|
Score = $Null
|
|
StatusCode = ""
|
|
Details = ""
|
|
ResponseTime = ""
|
|
}
|
|
|
|
# Préparation des paramètres pour Invoke-WebRequest (Splatting)
|
|
$IWRParams = @{
|
|
Uri = $Url
|
|
UseBasicParsing = $True
|
|
TimeoutSec = $Timeout
|
|
ErrorAction = 'Stop'
|
|
}
|
|
|
|
$Response = $Null
|
|
|
|
# Ajout des paramètres du proxy s'ils sont fournis
|
|
If (-not [string]::IsNullOrEmpty($ProxyAddress)) {
|
|
$IWRParams.Add('Proxy', $ProxyAddress)
|
|
|
|
If ($ProxyUseAuthentication) {
|
|
# Demande les identifiants de manière sécurisée et les ajoute à la commande
|
|
$Creds = Get-Credential -Message "Veuillez saisir les identifiants pour le proxy $ProxyAddress"
|
|
$IWRParams.Add('ProxyCredential', $Creds)
|
|
}
|
|
}
|
|
|
|
# -- Exécution du test --
|
|
Try {
|
|
# Exécution de la requête en utilisant les paramètres définis dans la hashtable
|
|
$Response = Invoke-WebRequest @IWRParams
|
|
|
|
# On vérifie si la réponse contient des mots-clés de la page de blocage
|
|
$KeywordFound = $False
|
|
|
|
Foreach ($Keyword in $BlockPageKeywords) {
|
|
If ($Response.Content -match $Keyword) {
|
|
$KeywordFound = $True
|
|
|
|
break
|
|
}
|
|
}
|
|
|
|
If ($KeywordFound) {
|
|
$Result.ActualResult = "Bloqué"
|
|
# $Result.Score = 1
|
|
$Result.Details = "Page de blocage détectée."
|
|
$Result.StatusCode = $Response.StatusCode
|
|
}
|
|
Else {
|
|
$Result.ActualResult = "Autorisé"
|
|
# $Result.Score = 0
|
|
$Result.Details = "Le site a été atteint sans blocage."
|
|
$Result.StatusCode = $Response.StatusCode
|
|
}
|
|
|
|
}
|
|
Catch [System.Net.WebException] {
|
|
If ($_.Exception.Status -eq 'Timeout') {
|
|
$Result.ActualResult = "Bloqué (Timeout)"
|
|
# $Result.Score = 1
|
|
$Result.Details = "La requête a expiré, indiquant un blocage probable par le pare-feu ou le proxy."
|
|
$Result.StatusCode = $Response.StatusCode
|
|
$Result.ResponseTime = "$Timeout"
|
|
}
|
|
# Elseif ($_.Exception.Response) {
|
|
# $Result.Status = "Bloqué (Erreur HTTP)"
|
|
# $Result.Score = 1
|
|
# $Result.Details = "Réponse HTTP non-200 reçue : $($_.Exception.Response.StatusCode)"
|
|
# }
|
|
Else {
|
|
# On considère les autres erreurs réseau comme un blocage aussi
|
|
$Result.ActualResult = "Erreur de Connexion"
|
|
$Result.Details = "Impossible de joindre le serveur : $($_.Exception.Status)"
|
|
$Result.StatusCode = $Response.StatusCode
|
|
}
|
|
}
|
|
Catch {
|
|
$Result.ActualResult = "Erreur Script"
|
|
$Result.Details = "Erreur inattendue: $($_.Exception.Message)"
|
|
|
|
#$Result.StatusCode = 0 <= A trouver
|
|
#$Result.ResponseTime = 0 <= A trouver
|
|
|
|
# Un test en erreur ne doit pas donner de point
|
|
return $result
|
|
}
|
|
|
|
# Le test est réussi si l'action attendue correspond au résultat réel.
|
|
If (($Result.Expected -eq 'block' -and $Result.ActualResult -eq 'Bloqué') -or ($Result.Expected -eq 'allow' -and $Result.ActualResult -eq 'Autorisé')) {
|
|
$Result.TestStatus = "Conforme"
|
|
$Result.Score = 1 # Le test est un succès !
|
|
$Result.Details += " (Résultat conforme à l'attendu)"
|
|
}
|
|
Else {
|
|
$Result.TestStatus = "Non Conforme"
|
|
$Result.Score = 0 # Le test est un échec !
|
|
$Result.Details += " (Résultat NON CONFORME; Attendu: $($Result.Expected); Obtenu: $($Result.ActualResult))"
|
|
}
|
|
|
|
Return $Result
|
|
}
|
|
|
|
## Function Generate-HtmlReport
|
|
Function Generate-HtmlReport {
|
|
Param(
|
|
[array]$Results,
|
|
[string]$OutputPath
|
|
)
|
|
|
|
Write-ColorOutput "Génération du rapport HTML..." "Yellow"
|
|
|
|
# Calcul des scores
|
|
$Categories = $Results | Group-Object Category
|
|
$CategoryScores = @()
|
|
|
|
Foreach ($Cat in $Categories) {
|
|
$Score = Calculate-CategoryScore -Results $Cat.Group
|
|
$Grade = Convert-ScoreToGrade -Score $Score
|
|
|
|
$CategoryScores += [PSCustomObject]@{
|
|
Category = $cat.Name
|
|
Score = $score
|
|
Grade = $grade
|
|
Color = $GradeColors[$grade]
|
|
TotalUrls = $cat.Group.Count
|
|
CorrectResults = ($cat.Group | Where-Object IsCorrect).Count
|
|
}
|
|
}
|
|
|
|
# Score global
|
|
$globalScore = Calculate-CategoryScore -Results $Results
|
|
$globalGrade = Convert-ScoreToGrade -Score $globalScore
|
|
|
|
# Création du rapport HTML
|
|
New-HTML -TitleText "Audit Firewall - Network Reputation Service" -Online -FilePath $OutputPath {
|
|
New-HTMLHeader {
|
|
New-HTMLText -Text "Audit Firewall - Network Reputation Service" -FontSize 28 -FontWeight bold -Color Blue -Alignment center
|
|
New-HTMLText -Text "Rapport généré le $(Get-Date -Format 'dd/MM/yyyy à HH:mm')" -FontSize 14 -Color Gray -Alignment center
|
|
}
|
|
|
|
New-HTMLSection -HeaderText "Résumé Exécutif" -BackgroundColor LightBlue {
|
|
New-HTMLPanel {
|
|
New-HTMLText -Text "Score Global: $globalScore% - Note: $globalGrade" -FontSize 24 -FontWeight bold -Color $GradeColors[$globalGrade]
|
|
New-HTMLText -Text "Total des URLs testées: $($Results.Count)" -FontSize 16
|
|
New-HTMLText -Text "URLs correctement filtrées: $(($Results | Where-Object IsCorrect).Count)" -FontSize 16
|
|
New-HTMLText -Text "Taux de réussite: $([math]::Round((($Results | Where-Object IsCorrect).Count / $Results.Count) * 100, 2))%" -FontSize 16
|
|
}
|
|
}
|
|
|
|
New-HTMLSection -HeaderText "Scores par Catégorie" -BackgroundColor LightGray {
|
|
New-HTMLTable -DataTable $categoryScores -HideFooter {
|
|
New-HTMLTableHeader -Names "Category", "Score", "Grade", "TotalUrls", "CorrectResults" -Title "Scores par Catégorie"
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'A+' -BackgroundColor '#28a745' -Color White
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'A' -BackgroundColor '#52b83a' -Color White
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'B+' -BackgroundColor '#7ac92e' -Color White
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'B' -BackgroundColor '#a3da23' -Color Black
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'C+' -BackgroundColor '#cceb17' -Color Black
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'C' -BackgroundColor '#f5f90c' -Color Black
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'D+' -BackgroundColor '#f7d808' -Color Black
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'D' -BackgroundColor '#f9b604' -Color Black
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'E+' -BackgroundColor '#fb9500' -Color White
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'E' -BackgroundColor '#fd7300' -Color White
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'F+' -BackgroundColor '#ff5100' -Color White
|
|
New-HTMLTableCondition -Name 'Grade' -ComparisonType string -Operator eq -Value 'F' -BackgroundColor '#dc3545' -Color White
|
|
}
|
|
}
|
|
|
|
New-HTMLSection -HeaderText "Détail des Tests par Catégorie" -BackgroundColor White {
|
|
foreach ($category in $categories) {
|
|
$catScore = ($categoryScores | Where-Object Category -eq $category.Name).Score
|
|
$catGrade = ($categoryScores | Where-Object Category -eq $category.Name).Grade
|
|
|
|
New-HTMLSection -HeaderText "$($category.Name) - Score: $catScore% ($catGrade)" -BackgroundColor LightYellow -Collapsible {
|
|
$detailedResults = $category.Group | Select-Object Url, Reputation, ExpectedAction, Status, IsCorrect, Error
|
|
New-HTMLTable -DataTable $detailedResults -HideFooter {
|
|
New-HTMLTableCondition -Name 'IsCorrect' -ComparisonType string -Operator eq -Value 'True' -BackgroundColor '#d4edda' -Color '#155724'
|
|
New-HTMLTableCondition -Name 'IsCorrect' -ComparisonType string -Operator eq -Value 'False' -BackgroundColor '#f8d7da' -Color '#721c24'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
New-HTMLSection -HeaderText "Barème de Notation" -BackgroundColor LightGreen -Collapsible {
|
|
$gradingScale = @(
|
|
[PSCustomObject]@{Grade='A+'; Score='95-100%'; Interpretation='Excellent / Parfait'}
|
|
[PSCustomObject]@{Grade='A'; Score='90-95%'; Interpretation='Très bon niveau de filtrage'}
|
|
[PSCustomObject]@{Grade='B+'; Score='85-90%'; Interpretation='Très bon'}
|
|
[PSCustomObject]@{Grade='B'; Score='80-85%'; Interpretation='Bon, mais quelques ajustements nécessaires'}
|
|
[PSCustomObject]@{Grade='C+'; Score='75-80%'; Interpretation='Assez bon'}
|
|
[PSCustomObject]@{Grade='C'; Score='70-75%'; Interpretation='Moyen, lacunes importantes'}
|
|
[PSCustomObject]@{Grade='D+'; Score='65-70%'; Interpretation='Passable'}
|
|
[PSCustomObject]@{Grade='D'; Score='60-65%'; Interpretation='Faible, filtrage inefficace'}
|
|
[PSCustomObject]@{Grade='E+'; Score='55-60%'; Interpretation='Très faible'}
|
|
[PSCustomObject]@{Grade='E'; Score='50-55%'; Interpretation='Insuffisant'}
|
|
[PSCustomObject]@{Grade='F+'; Score='45-50%'; Interpretation='Critique'}
|
|
[PSCustomObject]@{Grade='F'; Score='0-45%'; Interpretation='Très faible, action immédiate requise'}
|
|
)
|
|
|
|
New-HTMLTable -DataTable $gradingScale -HideFooter
|
|
}
|
|
}
|
|
|
|
Write-ColorOutput "✓ Rapport généré: $OutputPath" "Green"
|
|
}
|
|
|
|
## Function Main
|
|
Function Main {
|
|
Write-ColorOutput @"
|
|
╔══════════════════════════════════════════════════════════════════════════════╗
|
|
║ AUDIT FIREWALL - NETWORK REPUTATION SERVICE ║
|
|
║ Version 1.0 ║
|
|
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
"@ "Cyan"
|
|
|
|
# Vérification des prérequis
|
|
If(-not (Prerequisites)) {
|
|
Write-ColorOutput "ERREUR: Les prérequis ne sont pas satisfaits. Arrêt du script." "Red"
|
|
|
|
Return
|
|
}
|
|
|
|
# Chargement du fichier JSON
|
|
Try {
|
|
$JsonFile = Join-Path $PSScriptRoot "file-nrs.json"
|
|
$Categories = Get-Content $JsonFile -Raw -Encoding UTF8 | ConvertFrom-Json
|
|
|
|
Write-ColorOutput "✓ Fichier JSON chargé avec $($Categories.categorie.Count) catégories" "Green"
|
|
}
|
|
Catch {
|
|
Write-ColorOutput "ERREUR: Impossible de charger le fichier JSON: $($_.Exception.Message)" "Red"
|
|
|
|
Return
|
|
}
|
|
|
|
# Création du dossier de sortie
|
|
$ReportDate = Get-Date -Format "dddd dd MMMM yyyy-HH mm"
|
|
$ReportsDir = Join-Path $PSScriptRoot "Rapports"
|
|
$OutputDir = Join-Path $ReportsDir $ReportDate
|
|
|
|
If (-not (Test-Path $ReportsDir)) {
|
|
New-Item -ItemType Directory -Path $ReportsDir -Force | Out-Null
|
|
}
|
|
|
|
If (-not (Test-Path $OutputDir)) {
|
|
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
|
|
}
|
|
|
|
Write-ColorOutput "`n Dossier de sortie: $outputDir" "Yellow"
|
|
|
|
# Début des tests
|
|
Write-ColorOutput "`n=== DÉBUT DES TESTS ===" "Green"
|
|
$StartTime = Get-Date
|
|
|
|
$AllResults = Check-Categories -Categories $Categories -ProxyUrl $ProxyUrl -ProxyCredential $ProxyCredential -TimeoutSeconds $TimeoutSeconds -BlockPageKeywords $BlockKeywors
|
|
|
|
$EndTime = Get-Date
|
|
$Duration = $EndTime - $StartTime
|
|
|
|
Write-ColorOutput "`n=== RÉSULTATS FINAUX ===" "Green"
|
|
Write-ColorOutput "`n Temps total d'exécution: $($duration.ToString('hh\:mm\:ss'))" "Yellow"
|
|
Write-ColorOutput "`n Total des URLs testées: $($allResults.Count)" "Yellow"
|
|
|
|
# Calcul du score global
|
|
$GlobalScore = Calculate-CategoryScore -Results $AllResults
|
|
$GlobalGrade = Convert-ScoreToGrade -Score $GlobalScore
|
|
|
|
Write-ColorOutput "`n `n Score global: $GlobalScore% - Note: $GlobalGrade" "Magenta"
|
|
|
|
# Génération du rapport HTML
|
|
$ReportPath = Join-Path $OutputDir "Audit_Firewall_Report.html"
|
|
Generate-HtmlReport -Results $AllResults -OutputPath $ReportPath
|
|
|
|
# Sauvegarde des résultats en JSON
|
|
$JsonResultsPath = Join-Path $outputDir "Results.json"
|
|
$AllResults | ConvertTo-Json -Depth 10 | Out-File -FilePath $JsonResultsPath -Encoding UTF8
|
|
Write-ColorOutput "✓ Résultats sauvegardés: $JsonResultsPath" "Green"
|
|
|
|
Write-ColorOutput "`n=== AUDIT TERMINÉ ===" "Green"
|
|
Write-ColorOutput "Rapport disponible à: $ReportPath" "Cyan"
|
|
|
|
# Ouverture automatique du rapport
|
|
If (Get-Command "Start-Process" -ErrorAction SilentlyContinue) {
|
|
$OpenReport = Read-Host "Voulez-vous ouvrir le rapport maintenant? (O/N)"
|
|
If ($OpenReport -eq "O" -or $OpenReport -eq "o" -or $OpenReport -eq "Y" -or $OpenReport -eq "y") {
|
|
Start-Process $ReportPath
|
|
}
|
|
}
|
|
}
|
|
|
|
### Main
|
|
|
|
Clear-Host
|
|
|
|
# Exécution du script principal
|
|
Try {
|
|
Main
|
|
}
|
|
Catch {
|
|
Write-ColorOutput "ERREUR FATALE: $($_.Exception.Message)" "Red"
|
|
Write-ColorOutput "Stack Trace: $($_.ScriptStackTrace)" "Red"
|
|
}
|
|
|