Files

726 lines
28 KiB
PowerShell
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Script d'Audit Firewall - Network Reputation Service
# Auteur: Hubert Cornet
# Date: 03/09/2025
# Version: 1.2
Clear-Host
# Configuration globale
$ErrorActionPreference = "Continue"
$WarningPreference = "SilentlyContinue"
# Couleurs pour les grades
$GradeColors = @{
'A+' = '#28a745'
'A' = '#52b83a'
'B+' = '#7ac92e'
'B' = '#a3da23'
'C+' = '#cceb17'
'C' = '#f5f90c'
'D+' = '#f7d808'
'D' = '#f9b604'
'E+' = '#fb9500'
'E' = '#fd7300'
'F+' = '#ff5100'
'F' = '#dc3545'
}
### Functions ###
## Function Write-ColorOutput : pour afficher du texte en couleur
Function Write-ColorOutput {
Param(
[string]$Text,
[string]$Color = "White"
)
Try{
Write-Host $Text -ForegroundColor $Color
}
Catch {
Write-Host $Text
}
}
## Function Prerequisites : vérifie les prérequis
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://gitea.tips-of-mine.com/Tips-Of-Mine/Powershell/src/branch/main/cybersecurity/Network%20Reputation%20Service/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 : pour tester les catégories et URLs
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 -Id 1 -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 "`nDescription: $($Category.description)" "Gray"
$CategoryResults = @()
$UrlCount = 0
Foreach($UrlObj in $Category.urls) {
$UrlCount++
Show-ProgressBar -Id 2 -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 -Id 1 -Activity "Test des catégories" -Completed
Write-Progress -Id 2 -Activity "Test des URLs" -Completed
return $AllResults
}
## Function Show-ProgressBar : affiche une barre de progression
Function Show-ProgressBar {
Param(
[int]$Current,
[int]$Total,
[int]$Id,
[string]$Activity,
[string]$Status = ""
)
$Percent = [math]::Round(($Current / $Total) * 100, 1)
Write-Progress -Id $Id -Activity $Activity -Status "$Status ($Current/$Total)" -PercentComplete $Percent
}
## FunctionCalculate-CategoryScore : calcule le score d'une catégorie
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 : convertit un score en une note
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 : teste une URL et détermine si elle est bloquée ou autorisée
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.Details = "Page de blocage détectée."
$Result.StatusCode = $Response.StatusCode
}
Else {
$Result.ActualResult = "Autorisé"
$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.Details = "La requête a expiré, indiquant un blocage probable par le pare-feu ou le proxy."
$Result.StatusCode = $Response.StatusCode
$Result.ResponseTime = "$Timeout"
}
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)"
# 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 : génère le rapport HTML
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
Results = $Cat.Group
}
}
# Score global
$GlobalScore = Calculate-CategoryScore -Results $Results
$GlobalGrade = Convert-ScoreToGrade -Score $GlobalScore
$GlobalColor = $GradeColors[$GlobalGrade]
# Génération du HTML
$HtmlContent = @"
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Audit Firewall - Network Reputation Service</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f5f5f5; color: #333; line-height: 1.6; }
.container { max-width: 1200px; margin: 0 auto; padding: 20px; }
h1 { text-align: center; color: #2c3e50; margin-bottom: 10px; font-size: 2.5em; }
.subtitle { text-align: center; color: #666; margin-bottom: 30px; font-size: 1.1em; }
.section { background: white; margin: 20px 0; padding: 20px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
.section h2 { color: #2c3e50; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 2px solid #3498db; }
/* Score global */
.global-score { display: flex; align-items: center; justify-content: center; margin: 30px 0; }
.score-box { background-color: $globalColor; color: white; width: 150px; height: 150px; border-radius: 15px; display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: 0 4px 15px rgba(0,0,0,0.2); margin-right: 40px; }
.score-grade { font-size: 3em; font-weight: bold; }
.score-percent { font-size: 1.5em; margin-top: 5px; }
.score-label { font-size: 1em; margin-top: 5px; opacity: 0.9; }
.stats { text-align: left; }
.stats div { margin: 8px 0; font-size: 1.2em; }
/* Tableau des scores */
table { width: 100%; border-collapse: collapse; margin: 20px 0; }
th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }
th { background-color: #3498db; color: white; font-weight: bold; }
tr:nth-child(even) { background-color: #f9f9f9; }
tr:hover { background-color: #e8f4fd; }
.grade-cell { font-weight: bold; color: white; text-align: center; border-radius: 5px; }
/* Catégories en grille */
.categories-grid { display: flex; flex-wrap: wrap; gap: 20px; margin: 20px 0; }
.category-item { flex: 1; min-width: 280px; max-width: calc(25% - 15px); background: white; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); overflow: hidden; }
.category-header { padding: 15px; cursor: pointer; transition: background-color 0.3s; }
.category-header:hover { background-color: #f8f9fa; }
.category-title { font-size: 1.2em; font-weight: bold; margin-bottom: 8px; color: #2c3e50; }
.category-score { display: inline-block; padding: 5px 15px; border-radius: 20px; color: white; font-weight: bold; font-size: 0.9em; }
.category-content { display: none; padding: 0 15px 15px; }
.category-content.active { display: block; animation: slideDown 0.3s ease; }
/* Animations */
@keyframes slideDown { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
/* Tables détaillées */
.detail-table { font-size: 0.9em; }
.detail-table th { font-size: 0.8em; }
.correct { background-color: #d4edda !important; color: #155724; }
.incorrect { background-color: #f8d7da !important; color: #721c24; }
/* Barème */
.grading-scale { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 10px; }
.grade-item { display: flex; align-items: center; padding: 10px; border-radius: 8px; background-color: #f8f9fa; }
.grade-badge { width: 40px; height: 40px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-weight: bold; color: white; margin-right: 15px; }
/* Responsive */
@media (max-width: 768px) {
.global-score { flex-direction: column; }
.score-box { margin-right: 0; margin-bottom: 20px; }
.category-item { max-width: 100%; }
}
/* Bouton toggle */
.toggle-btn { float: right; font-size: 1.2em; transition: transform 0.3s; }
.toggle-btn.active { transform: rotate(180deg); }
</style>
</head>
<body>
<div class="container">
<h1>🛡 Audit Firewall - Network Reputation Service</h1>
<p class="subtitle">Rapport généré le $(Get-Date -Format 'dd/MM/yyyy à HH:mm')</p>
<!-- Résumé Exécutif -->
<div class="section">
<h2>📊 Résumé Exécutif</h2>
<div class="global-score">
<div class="score-box">
<div class="score-grade">$globalGrade</div>
<div class="score-percent">$globalScore%</div>
<div class="score-label">Score Global</div>
</div>
<div class="stats">
<div><strong>📋 Total des URLs testées :</strong> $($Results.Count)</div>
<div><strong> URLs correctement filtrées :</strong> $(($Results | Where-Object IsCorrect).Count)</div>
<div><strong>🎯 Taux de réussite :</strong> $([math]::Round((($Results | Where-Object IsCorrect).Count / $Results.Count) * 100, 2))%</div>
<div><strong>📅 Date du test :</strong> $(Get-Date -Format 'dd/MM/yyyy HH:mm')</div>
</div>
</div>
</div>
<!-- Scores par Catégorie -->
<div class="section">
<h2>📈 Scores par Catégorie</h2>
<table>
<thead>
<tr>
<th>Catégorie</th>
<th>Score (%)</th>
<th>Note</th>
<th>URLs Totales</th>
<th>Résultats Corrects</th>
</tr>
</thead>
<tbody>
"@
# Ajout des lignes du tableau
Foreach($CatScore in $CategoryScores) {
$HtmlContent += @"
<tr>
<td><strong>$($catScore.Category)</strong></td>
<td>$($catScore.Score)%</td>
<td><span class="grade-cell" style="background-color: $($catScore.Color); padding: 5px 10px; border-radius: 5px;">$($catScore.Grade)</span></td>
<td>$($catScore.TotalUrls)</td>
<td>$($catScore.CorrectResults)</td>
</tr>
"@
}
$HtmlContent += @"
</tbody>
</table>
</div>
<!-- Détail des Tests par Catégorie -->
<div class="section">
<h2>🔍 Détail des Tests par Catégorie</h2>
<div class="categories-grid">
"@
# Ajout des catégories
$CategoryIndex = 0
Foreach($CatScore in $CategoryScores) {
$CategoryIndex++
$HtmlContent += @"
<div class="category-item">
<div class="category-header" onclick="toggleCategory('cat-$CategoryIndex')">
<div class="category-title">$($CatScore.Category) <span class="toggle-btn" id="btn-cat-$CategoryIndex"></span></div>
<span class="category-score" style="background-color: $($CatScore.Color);">$($CatScore.Grade) - $($CatScore.Score)%</span>
</div>
<div class="category-content" id="cat-$CategoryIndex">
<table class="detail-table">
<thead>
<tr>
<th>URL</th>
<th>Réputation</th>
<th>Action Attendue</th>
<th>Statut</th>
<th>Correct</th>
</tr>
</thead>
<tbody>
"@
# Ajout des résultats de chaque URL
Foreach($Result in $CatScore.Results) {
$RowClass = if($Result.IsCorrect) { "correct" } else { "incorrect" }
$CorrectText = if($Result.IsCorrect) { "✅ Oui" } else { "❌ Non" }
$HtmlContent += @"
<tr class="$RowClass">
<td title="$($Result.Url)">$($result.Url.Substring(0, [Math]::Min(30, $Result.Url.Length)))$(if($Result.Url.Length -gt 30){"..."})</td>
<td>$($Result.Reputation)</td>
<td>$($Result.ExpectedAction)</td>
<td>$($Result.Status)</td>
<td>$CorrectText</td>
</tr>
"@
}
$HtmlContent += @"
</tbody>
</table>
</div>
</div>
"@
}
$HtmlContent += @"
</div>
</div>
<!-- Barème de Notation -->
<div class="section">
<h2>📏 Barème de Notation</h2>
<div class="grading-scale">
"@
# Ajout du barème de notation
$gradingScale = @(
@{Grade='A+'; Score='95-100%'; Interpretation='Excellent / Parfait'; Color='#28a745'}
@{Grade='A'; Score='90-95%'; Interpretation='Très bon niveau de filtrage'; Color='#52b83a'}
@{Grade='B+'; Score='85-90%'; Interpretation='Très bon'; Color='#7ac92e'}
@{Grade='B'; Score='80-85%'; Interpretation='Bon, quelques ajustements nécessaires'; Color='#a3da23'}
@{Grade='C+'; Score='75-80%'; Interpretation='Assez bon'; Color='#cceb17'}
@{Grade='C'; Score='70-75%'; Interpretation='Moyen, lacunes importantes'; Color='#f5f90c'}
@{Grade='D+'; Score='65-70%'; Interpretation='Passable'; Color='#f7d808'}
@{Grade='D'; Score='60-65%'; Interpretation='Faible, filtrage inefficace'; Color='#f9b604'}
@{Grade='E+'; Score='55-60%'; Interpretation='Très faible'; Color='#fb9500'}
@{Grade='E'; Score='50-55%'; Interpretation='Insuffisant'; Color='#fd7300'}
@{Grade='F+'; Score='45-50%'; Interpretation='Critique'; Color='#ff5100'}
@{Grade='F'; Score='0-45%'; Interpretation='Très faible, action immédiate requise'; Color='#dc3545'}
)
Foreach($GradeInfo in $GradingScale) {
$HtmlContent += @"
<div class="grade-item">
<div class="grade-badge" style="background-color: $($GradeInfo.Color);">$($GradeInfo.Grade)</div>
<div>
<strong>$($GradeInfo.Score)</strong><br>
<span style="color: #666;">$($GradeInfo.Interpretation)</span>
</div>
</div>
"@
}
$HtmlContent += @"
</div>
</div>
</div>
<script>
function toggleCategory(categoryId) {
const content = document.getElementById(categoryId);
const btn = document.getElementById('btn-' + categoryId);
If(content.classList.contains('active')) {
content.classList.remove('active');
btn.classList.remove('active');
content.style.display = 'none';
}
Else {
content.classList.add('active');
btn.classList.add('active');
content.style.display = 'block';
}
}
// Animation au chargement
document.addEventListener('DOMContentLoaded', function() {
const items = document.querySelectorAll('.category-item');
items.forEach((item, index) => {
setTimeout(() => {
item.style.opacity = '1';
item.style.transform = 'translateY(0)';
}, index * 100);
});
});
</script>
</body>
</html>
"@
# Écriture du fichier HTML
Try{
$HtmlContent | Out-File -FilePath $OutputPath -Encoding UTF8
Write-ColorOutput "✓ Rapport généré: $OutputPath" "Green"
}
Catch {
Write-ColorOutput "ERREUR: Impossible de générer le rapport: $($_.Exception.Message)" "Red"
}
}
## Function Main : fonction principale
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 "`n Rapport disponible à: $ReportPath" "Cyan"
# Ouverture automatique du rapport
If(Get-Command "Start-Process" -ErrorAction SilentlyContinue) {
$OpenReport = Read-Host "`n 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"
}