Update cybersecurity/Network Reputation Service/script-nrs.ps1
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Script d'Audit Firewall - Network Reputation Service
|
||||
# Auteur: Hubert Cornet
|
||||
# Date: 03/09/2025
|
||||
# Version: 1.0
|
||||
# Version: 1.1
|
||||
|
||||
Clear-Host
|
||||
|
||||
@@ -9,6 +9,22 @@ Clear-Host
|
||||
$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
|
||||
@@ -337,89 +353,285 @@ Function Generate-HtmlReport {
|
||||
$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
|
||||
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
|
||||
$GlobalScore = Calculate-CategoryScore -Results $Results
|
||||
$GlobalGrade = Convert-ScoreToGrade -Score $GlobalScore
|
||||
$GlobalColor = $GradeColors[$globalGrade]
|
||||
|
||||
# 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
|
||||
# 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%; }
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
/* 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>
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
<!-- 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>
|
||||
|
||||
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
|
||||
<!-- 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>
|
||||
"@
|
||||
|
||||
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
|
||||
}
|
||||
# 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>
|
||||
"@
|
||||
}
|
||||
|
||||
Write-ColorOutput "✓ Rapport généré: $OutputPath" "Green"
|
||||
$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
|
||||
@@ -495,11 +707,11 @@ Function Main {
|
||||
Write-ColorOutput "✓ Résultats sauvegardés: $JsonResultsPath" "Green"
|
||||
|
||||
Write-ColorOutput "`n=== AUDIT TERMINÉ ===" "Green"
|
||||
Write-ColorOutput "Rapport disponible à: $ReportPath" "Cyan"
|
||||
Write-ColorOutput "`n 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)"
|
||||
$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
|
||||
}
|
||||
|
Reference in New Issue
Block a user