powershell max theme bind
# NetScaler Authentication Policy Analyzer
# ============================================================================
# Script d'analyse des Portal Themes NetScaler
# ============================================================================
# Ce script analyse le fichier ns.conf pour identifier :
# - Tous les portal themes définis (add vpn portaltheme)
# - Leurs bindings sur vpn vserver (Citrix Gateway)
# - Leurs bindings sur authentication vserver (AAA)
# - Les themes orphelins (non bindés) à supprimer
#
# Auteur : Maximilien (ITMAX)
# Version : 1.0
# Date : 12/11/2025
# ============================================================================
param(
[Parameter(Mandatory=$false)]
[string]$ConfigPath = "C:\logs\ns.conf"
)
# ============================================================================
# FONCTIONS UTILITAIRES
# ============================================================================
function Write-Header {
param([string]$Title)
Write-Host ""
Write-Host "===============================================================================" -ForegroundColor Cyan
Write-Host " $Title" -ForegroundColor Yellow
Write-Host "===============================================================================" -ForegroundColor Cyan
Write-Host ""
}
function Write-Section {
param([string]$Title)
Write-Host ""
Write-Host "-------------------------------------------------------------------------------" -ForegroundColor DarkCyan
Write-Host " $Title" -ForegroundColor White
Write-Host "-------------------------------------------------------------------------------" -ForegroundColor DarkCyan
Write-Host ""
}
function Write-SubSection {
param([string]$Title)
Write-Host ""
Write-Host " $Title" -ForegroundColor Gray
Write-Host " " + ("-" * ($Title.Length)) -ForegroundColor DarkGray
}
# ============================================================================
# CHARGEMENT ET VALIDATION DU FICHIER
# ============================================================================
Write-Header "ANALYSE DES PORTAL THEMES NETSCALER"
Write-Host "Fichier analyse : " -NoNewline -ForegroundColor White
Write-Host $ConfigPath -ForegroundColor Cyan
if (-not (Test-Path $ConfigPath)) {
Write-Host ""
Write-Host "ERREUR : Le fichier $ConfigPath est introuvable !" -ForegroundColor Red
Write-Host ""
exit 1
}
Write-Host "Fichier trouve - Chargement en cours..." -ForegroundColor Green
Write-Host ""
$configContent = Get-Content -Path $ConfigPath -Encoding UTF8 -ErrorAction Stop
Write-Host "Nombre de lignes : " -NoNewline -ForegroundColor White
Write-Host $configContent.Count -ForegroundColor Yellow
# ============================================================================
# PATTERNS DE RECHERCHE
# ============================================================================
$patterns = @{
AddTheme = 'add\s+vpn\s+portaltheme\s+([^\s]+)'
BindVpnVserver = 'bind\s+vpn\s+vserver\s+([^\s]+)\s+.*-portaltheme\s+([^\s]+)'
BindAuthVserver = 'bind\s+authentication\s+vserver\s+([^\s]+)\s+.*-portaltheme\s+([^\s]+)'
}
# ============================================================================
# COLLECTE DES DONNÉES
# ============================================================================
Write-Section "ANALYSE DU FICHIER ns.conf"
# Structures de données
$allThemes = @{} # Tous les themes définis
$vpnBindings = @{} # Bindings sur vpn vserver
$authBindings = @{} # Bindings sur authentication vserver
Write-Host " Recherche des portal themes..." -ForegroundColor Gray
# 1. Collecter tous les themes définis
foreach ($line in $configContent) {
if ($line -match $patterns.AddTheme) {
$themeName = $Matches[1]
if (-not $allThemes.ContainsKey($themeName)) {
$allThemes[$themeName] = @{
Name = $themeName
VpnVservers = @()
AuthVservers = @()
}
}
}
}
Write-Host " Trouve : " -NoNewline -ForegroundColor Gray
Write-Host "$($allThemes.Count) themes" -ForegroundColor Yellow
Write-Host " Recherche des bindings vpn vserver..." -ForegroundColor Gray
# 2. Collecter les bindings sur vpn vserver
foreach ($line in $configContent) {
if ($line -match $patterns.BindVpnVserver) {
$vserverName = $Matches[1]
$themeName = $Matches[2]
if ($allThemes.ContainsKey($themeName)) {
$allThemes[$themeName].VpnVservers += $vserverName
}
}
}
$totalVpnBindings = ($allThemes.Values | ForEach-Object { $_.VpnVservers.Count } | Measure-Object -Sum).Sum
Write-Host " Trouve : " -NoNewline -ForegroundColor Gray
Write-Host "$totalVpnBindings bindings sur vpn vserver" -ForegroundColor Yellow
Write-Host " Recherche des bindings authentication vserver..." -ForegroundColor Gray
# 3. Collecter les bindings sur authentication vserver
foreach ($line in $configContent) {
if ($line -match $patterns.BindAuthVserver) {
$vserverName = $Matches[1]
$themeName = $Matches[2]
if ($allThemes.ContainsKey($themeName)) {
$allThemes[$themeName].AuthVservers += $vserverName
}
}
}
$totalAuthBindings = ($allThemes.Values | ForEach-Object { $_.AuthVservers.Count } | Measure-Object -Sum).Sum
Write-Host " Trouve : " -NoNewline -ForegroundColor Gray
Write-Host "$totalAuthBindings bindings sur authentication vserver" -ForegroundColor Yellow
# ============================================================================
# CALCUL DES STATISTIQUES
# ============================================================================
$boundThemes = @()
$unboundThemes = @()
foreach ($theme in $allThemes.Values) {
$totalBindings = $theme.VpnVservers.Count + $theme.AuthVservers.Count
if ($totalBindings -gt 0) {
$boundThemes += $theme
} else {
$unboundThemes += $theme
}
}
# ============================================================================
# AFFICHAGE DU RÉSUMÉ
# ============================================================================
Write-Section "RESUME DE L'ANALYSE"
Write-Host " Total Portal Themes : " -NoNewline
Write-Host $allThemes.Count -ForegroundColor Yellow
Write-Host " +- " -NoNewline -ForegroundColor DarkGray
Write-Host "Themes bindes : " -NoNewline
Write-Host $boundThemes.Count -ForegroundColor Green
Write-Host " +- " -NoNewline -ForegroundColor DarkGray
Write-Host "Themes orphelins : " -NoNewline
Write-Host $unboundThemes.Count -ForegroundColor Red
Write-Host ""
Write-Host " Total Bindings : " -NoNewline
Write-Host ($totalVpnBindings + $totalAuthBindings) -ForegroundColor Yellow
Write-Host " +- " -NoNewline -ForegroundColor DarkGray
Write-Host "VPN vserver : " -NoNewline
Write-Host $totalVpnBindings -ForegroundColor Cyan
Write-Host " +- " -NoNewline -ForegroundColor DarkGray
Write-Host "AAA vserver : " -NoNewline
Write-Host $totalAuthBindings -ForegroundColor Magenta
# ============================================================================
# AFFICHAGE DES THEMES BINDÉS
# ============================================================================
if ($boundThemes.Count -gt 0) {
Write-Section "PORTAL THEMES BINDES ($($boundThemes.Count))"
$sortedBoundThemes = $boundThemes | Sort-Object { $_.Name }
foreach ($theme in $sortedBoundThemes) {
$totalBindings = $theme.VpnVservers.Count + $theme.AuthVservers.Count
Write-Host ""
Write-Host " [OK] " -NoNewline -ForegroundColor Green
Write-Host $theme.Name -NoNewline -ForegroundColor Green
Write-Host " ($totalBindings binding(s))" -ForegroundColor DarkGray
# Afficher les bindings VPN vserver
if ($theme.VpnVservers.Count -gt 0) {
Write-Host " +- VPN vserver (" -NoNewline -ForegroundColor DarkGray
Write-Host $theme.VpnVservers.Count -NoNewline -ForegroundColor Cyan
Write-Host ")" -ForegroundColor DarkGray
for ($i = 0; $i -lt $theme.VpnVservers.Count; $i++) {
$isLast = ($i -eq $theme.VpnVservers.Count - 1) -and ($theme.AuthVservers.Count -eq 0)
$prefix = if ($isLast) { " | +-" } else { " | +-" }
Write-Host "$prefix " -NoNewline -ForegroundColor DarkGray
Write-Host $theme.VpnVservers[$i] -ForegroundColor Cyan
}
}
# Afficher les bindings AAA vserver
if ($theme.AuthVservers.Count -gt 0) {
Write-Host " +- AAA vserver (" -NoNewline -ForegroundColor DarkGray
Write-Host $theme.AuthVservers.Count -NoNewline -ForegroundColor Magenta
Write-Host ")" -ForegroundColor DarkGray
for ($i = 0; $i -lt $theme.AuthVservers.Count; $i++) {
$isLast = $i -eq $theme.AuthVservers.Count - 1
$prefix = if ($isLast) { " +-" } else { " +-" }
Write-Host "$prefix " -NoNewline -ForegroundColor DarkGray
Write-Host $theme.AuthVservers[$i] -ForegroundColor Magenta
}
}
}
}
# ============================================================================
# AFFICHAGE DES THEMES ORPHELINS
# ============================================================================
if ($unboundThemes.Count -gt 0) {
Write-Section "PORTAL THEMES ORPHELINS (NON BINDES) - $($unboundThemes.Count)"
Write-Host " ATTENTION : Ces themes ne sont bindes a aucun vserver et peuvent etre supprimes" -ForegroundColor Yellow
Write-Host ""
$sortedUnboundThemes = $unboundThemes | Sort-Object { $_.Name }
foreach ($theme in $sortedUnboundThemes) {
Write-Host " [NON BINDE] " -NoNewline -ForegroundColor Red
Write-Host $theme.Name -ForegroundColor Red
}
# ============================================================================
# GÉNÉRATION DES COMMANDES DE SUPPRESSION
# ============================================================================
Write-Section "COMMANDES DE SUPPRESSION"
Write-Host " Copiez et executez ces commandes pour supprimer les themes orphelins :" -ForegroundColor Yellow
Write-Host ""
foreach ($theme in $sortedUnboundThemes) {
Write-Host " rm vpn portaltheme $($theme.Name)" -ForegroundColor DarkGray
}
Write-Host ""
Write-Host " Pour sauvegarder la configuration apres suppression :" -ForegroundColor Yellow
Write-Host " save ns config" -ForegroundColor DarkGray
} else {
Write-Section "AUCUN THEME ORPHELIN DETECTE"
Write-Host " Tous les portal themes sont correctement bindes !" -ForegroundColor Green
}
# ============================================================================
# FOOTER
# ============================================================================
Write-Host ""
Write-Host "===============================================================================" -ForegroundColor Cyan
Write-Host " Analyse terminee avec succes !" -ForegroundColor Green
Write-Host "===============================================================================" -ForegroundColor Cyan
Write-Host ""