powershell max LB VSERVER
# NetScaler Load Balancing Objects Analyzer v1.0
# Analyse: Monitor -> Service -> ServiceGroup -> LB vServer
$NS_CONF_PATH = "C:\logs\ns.conf"
# EXTRACTION
function Get-LBVServers { param([string[]]$L); $v=@{}; foreach($l in $L){if($l -match "^add lb vserver\s+(\S+)"){$v[$Matches[1].Trim('"')]=@{'Line'=$l}}}; $v }
function Get-ServiceGroups { param([string[]]$L); $s=@{}; foreach($l in $L){if($l -match "^add serviceGroup\s+(\S+)"){$s[$Matches[1].Trim('"')]=@{'Line'=$l}}}; $s }
function Get-Services { param([string[]]$L); $s=@{}; foreach($l in $L){if($l -match "^add service\s+(\S+)"){$s[$Matches[1].Trim('"')]=@{'Line'=$l}}}; $s }
function Get-Monitors { param([string[]]$L); $m=@{}; foreach($l in $L){if($l -match "^add lb monitor\s+(\S+)"){$m[$Matches[1].Trim('"')]=@{'Line'=$l}}}; $m }
function Get-ServiceGroupBindings {
param([string[]]$L,[hashtable]$SG)
$b=@{}
foreach($l in $L){
if($l -match "^bind lb vserver\s+(\S+)\s+(\S+)"){
$vs=$Matches[1].Trim('"');$t=$Matches[2].Trim('"')
if($SG.ContainsKey($t)){if(-not $b.ContainsKey($t)){$b[$t]=@()}; $b[$t]+=@{'VServer'=$vs;'Line'=$l}}
}
}
$b
}
function Get-ServiceBindingsToVServer {
param([string[]]$L,[hashtable]$S)
$b=@{}
foreach($l in $L){
if($l -match "^bind lb vserver\s+(\S+)\s+(\S+)"){
$vs=$Matches[1].Trim('"');$t=$Matches[2].Trim('"')
if($S.ContainsKey($t)){if(-not $b.ContainsKey($t)){$b[$t]=@()}; $b[$t]+=@{'VServer'=$vs;'Line'=$l}}
}
}
$b
}
function Get-ServiceGroupMembers {
param([string[]]$L)
$m=@{}
foreach($l in $L){
if($l -match "^bind serviceGroup\s+(\S+)\s+(\d+\.\d+\.\d+\.\d+)\s+(\d+)"){
$g=$Matches[1].Trim('"')
if(-not $m.ContainsKey($g)){$m[$g]=@()}
$m[$g]+=@{'IP'=$Matches[2];'Port'=$Matches[3];'Line'=$l}
}
}
$m
}
function Get-MonitorBindings {
param([string[]]$L)
$u=@{}
foreach($l in $L){
if($l -match "^bind service\s+(\S+)\s+-monitorName\s+(\S+)"){
$s=$Matches[1].Trim('"');$mn=$Matches[2].Trim('"')
if(-not $u.ContainsKey($mn)){$u[$mn]=@{'Services'=@();'ServiceGroups'=@()}}
$u[$mn]['Services']+=@{'Name'=$s;'Line'=$l}
}
if($l -match "^bind serviceGroup\s+(\S+)\s+-monitorName\s+(\S+)"){
$g=$Matches[1].Trim('"');$mn=$Matches[2].Trim('"')
if(-not $u.ContainsKey($mn)){$u[$mn]=@{'Services'=@();'ServiceGroups'=@()}}
$u[$mn]['ServiceGroups']+=@{'Name'=$g;'Line'=$l}
}
}
$u
}
function Get-UsedMonitors {
param([hashtable]$MB,[hashtable]$BSG,[hashtable]$BSvc)
$u=@{}
foreach($mn in $MB.Keys){
$d=@()
foreach($svc in $MB[$mn]['Services']){if($BSvc.ContainsKey($svc['Name'])){$d+=@{'Type'='Service';'Name'=$svc['Name'];'Line'=$svc['Line']}}}
foreach($sg in $MB[$mn]['ServiceGroups']){if($BSG.ContainsKey($sg['Name'])){$d+=@{'Type'='ServiceGroup';'Name'=$sg['Name'];'Line'=$sg['Line']}}}
if($d.Count -gt 0){$u[$mn]=$d}
}
$u
}
# AFFICHAGE ROUGE - NON UTILISES
function Show-UnusedServiceGroups {
param([hashtable]$SG,[hashtable]$BSG)
Write-Host "`n==================================================================" -ForegroundColor Red
Write-Host " SERVICE GROUPS NON UTILISES" -ForegroundColor Red -BackgroundColor Black
Write-Host "==================================================================" -ForegroundColor Red
$unused=@(); foreach($n in ($SG.Keys|Sort-Object)){if(-not $BSG.ContainsKey($n)){$unused+=$n}}
if($unused.Count -eq 0){Write-Host "`nAucun service group non utilise !" -ForegroundColor Green}
else{
Write-Host "`nNombre: $($unused.Count)" -ForegroundColor Red
foreach($n in $unused){
Write-Host " |-- $n" -ForegroundColor Red
Write-Host " | $($SG[$n]['Line'])" -ForegroundColor White
Write-Host " | rm serviceGroup $n" -ForegroundColor White
}
}
}
function Show-UnusedServices {
param([hashtable]$S,[hashtable]$BSvc)
Write-Host "`n==================================================================" -ForegroundColor Red
Write-Host " SERVICES NON UTILISES" -ForegroundColor Red -BackgroundColor Black
Write-Host "==================================================================" -ForegroundColor Red
$unused=@(); foreach($n in ($S.Keys|Sort-Object)){if(-not $BSvc.ContainsKey($n)){$unused+=$n}}
if($unused.Count -eq 0){Write-Host "`nAucun service non utilise !" -ForegroundColor Green}
else{
Write-Host "`nNombre: $($unused.Count)" -ForegroundColor Red
foreach($n in $unused){
Write-Host " |-- $n" -ForegroundColor Red
Write-Host " | $($S[$n]['Line'])" -ForegroundColor White
Write-Host " | rm service $n" -ForegroundColor White
}
}
}
function Show-UnusedMonitors {
param([hashtable]$M,[hashtable]$UM,[hashtable]$MB)
Write-Host "`n==================================================================" -ForegroundColor Red
Write-Host " MONITORS NON UTILISES" -ForegroundColor Red -BackgroundColor Black
Write-Host "==================================================================" -ForegroundColor Red
$orph=@();$bnd=@{}
foreach($n in ($M.Keys|Sort-Object)){
if(-not $UM.ContainsKey($n)){
if($MB.ContainsKey($n)){
$r=@()
foreach($svc in $MB[$n]['Services']){$r+="Service: $($svc['Name']) (non binde)"}
foreach($sg in $MB[$n]['ServiceGroups']){$r+="ServiceGroup: $($sg['Name']) (non binde)"}
$bnd[$n]=$r
}else{$orph+=$n}
}
}
$t=$orph.Count+$bnd.Count
if($t -eq 0){Write-Host "`nAucun monitor non utilise !" -ForegroundColor Green}
else{
Write-Host "`nNombre: $t" -ForegroundColor Red
if($orph.Count -gt 0){
Write-Host "`n[1] Orphelins (aucun binding): $($orph.Count)" -ForegroundColor Yellow
foreach($n in $orph){
Write-Host " |-- $n" -ForegroundColor Red
Write-Host " | $($M[$n]['Line'])" -ForegroundColor White
Write-Host " | rm lb monitor $n" -ForegroundColor White
}
}
if($bnd.Count -gt 0){
Write-Host "`n[2] Bindes a objets non utilises: $($bnd.Count)" -ForegroundColor Yellow
foreach($n in ($bnd.Keys|Sort-Object)){
Write-Host " |-- $n" -ForegroundColor Red
Write-Host " | $($M[$n]['Line'])" -ForegroundColor White
Write-Host " | Reference par:" -ForegroundColor DarkGray
foreach($r in $bnd[$n]){Write-Host " | * $r" -ForegroundColor Yellow}
Write-Host " | rm lb monitor $n" -ForegroundColor White
}
}
}
}
# AFFICHAGE VERT - UTILISES
function Show-UsedServiceGroups {
param([hashtable]$SG,[hashtable]$BSG,[hashtable]$M)
Write-Host "`n==================================================================" -ForegroundColor Green
Write-Host " SERVICE GROUPS UTILISES" -ForegroundColor Green -BackgroundColor Black
Write-Host "==================================================================" -ForegroundColor Green
$used=@(); foreach($n in ($SG.Keys|Sort-Object)){if($BSG.ContainsKey($n)){$used+=$n}}
if($used.Count -eq 0){Write-Host "`nAucun service group utilise !" -ForegroundColor Yellow}
else{
Write-Host "`nNombre: $($used.Count)" -ForegroundColor Green
foreach($n in $used){
Write-Host " |-- $n" -ForegroundColor Green
Write-Host " | $($SG[$n]['Line'])" -ForegroundColor White
Write-Host " | Binde sur:" -ForegroundColor DarkGray
foreach($b in $BSG[$n]){
Write-Host " | * LB vServer: $($b['VServer'])" -ForegroundColor Cyan
Write-Host " | $($b['Line'])" -ForegroundColor White
}
if($M.ContainsKey($n)){Write-Host " | Membres: $($M[$n].Count)" -ForegroundColor DarkGray}
}
}
}
function Show-UsedServices {
param([hashtable]$S,[hashtable]$BSvc,[hashtable]$MB)
Write-Host "`n==================================================================" -ForegroundColor Green
Write-Host " SERVICES UTILISES" -ForegroundColor Green -BackgroundColor Black
Write-Host "==================================================================" -ForegroundColor Green
$used=@(); foreach($n in ($S.Keys|Sort-Object)){if($BSvc.ContainsKey($n)){$used+=$n}}
if($used.Count -eq 0){Write-Host "`nAucun service utilise !" -ForegroundColor Yellow}
else{
Write-Host "`nNombre: $($used.Count)" -ForegroundColor Green
foreach($n in $used){
Write-Host " |-- $n" -ForegroundColor Green
Write-Host " | $($S[$n]['Line'])" -ForegroundColor White
Write-Host " | Binde sur:" -ForegroundColor DarkGray
foreach($b in $BSvc[$n]){
Write-Host " | * LB vServer: $($b['VServer'])" -ForegroundColor Cyan
Write-Host " | $($b['Line'])" -ForegroundColor White
}
$mf=$false
foreach($mn in $MB.Keys){foreach($svc in $MB[$mn]['Services']){if($svc['Name'] -eq $n){Write-Host " | Monitor: $mn" -ForegroundColor Yellow; $mf=$true}}}
if(-not $mf){Write-Host " | Monitor: tcp-default (implicite)" -ForegroundColor DarkYellow}
}
}
}
function Show-UsedMonitors {
param([hashtable]$M,[hashtable]$UM)
Write-Host "`n==================================================================" -ForegroundColor Green
Write-Host " MONITORS UTILISES" -ForegroundColor Green -BackgroundColor Black
Write-Host "==================================================================" -ForegroundColor Green
$used=@(); foreach($n in ($M.Keys|Sort-Object)){if($UM.ContainsKey($n)){$used+=$n}}
if($used.Count -eq 0){Write-Host "`nAucun monitor utilise !" -ForegroundColor Yellow}
else{
Write-Host "`nNombre: $($used.Count)" -ForegroundColor Green
foreach($n in $used){
Write-Host " |-- $n" -ForegroundColor Green
Write-Host " | $($M[$n]['Line'])" -ForegroundColor White
Write-Host " | Binde sur:" -ForegroundColor DarkGray
foreach($u in $UM[$n]){
Write-Host " | * $($u['Type']): $($u['Name'])" -ForegroundColor Cyan
Write-Host " | $($u['Line'])" -ForegroundColor White
}
}
}
}
# MAIN
Clear-Host
Write-Host "`n=== Analyse Load Balancing NetScaler v1.0 ===" -ForegroundColor Yellow
Write-Host "=== Monitor -> Service -> ServiceGroup -> LB vServer ===" -ForegroundColor DarkGray
if(-not (Test-Path $NS_CONF_PATH)){Write-Host "[ERREUR] Fichier introuvable: $NS_CONF_PATH" -ForegroundColor Red; exit 1}
Write-Host "`n[INFO] Chargement: $NS_CONF_PATH" -ForegroundColor Cyan
$lines = Get-Content -Path $NS_CONF_PATH -Encoding UTF8
Write-Host "[INFO] $($lines.Count) lignes chargees" -ForegroundColor Green
Write-Host "`n[ETAPE 1] Extraction des objets..." -ForegroundColor Cyan
$lbVS = Get-LBVServers -L $lines
$svcGrp = Get-ServiceGroups -L $lines
$svc = Get-Services -L $lines
$mon = Get-Monitors -L $lines
Write-Host "[ETAPE 2] Analyse des bindings..." -ForegroundColor Cyan
$bndSG = Get-ServiceGroupBindings -L $lines -SG $svcGrp
$bndSvc = Get-ServiceBindingsToVServer -L $lines -S $svc
$sgMembers = Get-ServiceGroupMembers -L $lines
$monBind = Get-MonitorBindings -L $lines
Write-Host "[ETAPE 3] Analyse en cascade des monitors..." -ForegroundColor Cyan
$usedMon = Get-UsedMonitors -MB $monBind -BSG $bndSG -BSvc $bndSvc
# Stats
$uSG=($svcGrp.Keys|Where-Object{-not $bndSG.ContainsKey($_)}).Count
$uSvc=($svc.Keys|Where-Object{-not $bndSvc.ContainsKey($_)}).Count
$uMon=($mon.Keys|Where-Object{-not $usedMon.ContainsKey($_)}).Count
Write-Host "`n==================================================================" -ForegroundColor Cyan
Write-Host " RESUME" -ForegroundColor Yellow
Write-Host "==================================================================" -ForegroundColor Cyan
Write-Host "`n LB vServers: $($lbVS.Count)" -ForegroundColor White
Write-Host " ServiceGroups: $($svcGrp.Count) total | " -NoNewline; Write-Host "$($svcGrp.Count-$uSG) utilises " -NoNewline -ForegroundColor Green; Write-Host "| " -NoNewline; Write-Host "$uSG non utilises" -ForegroundColor Red
Write-Host " Services: $($svc.Count) total | " -NoNewline; Write-Host "$($svc.Count-$uSvc) utilises " -NoNewline -ForegroundColor Green; Write-Host "| " -NoNewline; Write-Host "$uSvc non utilises" -ForegroundColor Red
Write-Host " Monitors: $($mon.Count) total | " -NoNewline; Write-Host "$($mon.Count-$uMon) utilises " -NoNewline -ForegroundColor Green; Write-Host "| " -NoNewline; Write-Host "$uMon non utilises" -ForegroundColor Red
# Commandes de suppression
$tot=$uSG+$uSvc+$uMon
if($tot -gt 0){
Write-Host "`n==================================================================" -ForegroundColor Yellow
Write-Host " COMMANDES DE SUPPRESSION (dans l'ordre)" -ForegroundColor Yellow -BackgroundColor Black
Write-Host "==================================================================" -ForegroundColor Yellow
Write-Host "`n# 1. D'abord les monitors" -ForegroundColor DarkGray
foreach($n in ($mon.Keys|Sort-Object)){if(-not $usedMon.ContainsKey($n)){Write-Host "rm lb monitor $n"}}
Write-Host "`n# 2. Ensuite les services" -ForegroundColor DarkGray
foreach($n in ($svc.Keys|Sort-Object)){if(-not $bndSvc.ContainsKey($n)){Write-Host "rm service $n"}}
Write-Host "`n# 3. Puis les service groups" -ForegroundColor DarkGray
foreach($n in ($svcGrp.Keys|Sort-Object)){if(-not $bndSG.ContainsKey($n)){Write-Host "rm serviceGroup $n"}}
}
# Details par type - ROUGE puis VERT
Show-UnusedServiceGroups -SG $svcGrp -BSG $bndSG
Show-UsedServiceGroups -SG $svcGrp -BSG $bndSG -M $sgMembers
Show-UnusedServices -S $svc -BSvc $bndSvc
Show-UsedServices -S $svc -BSvc $bndSvc -MB $monBind
Show-UnusedMonitors -M $mon -UM $usedMon -MB $monBind
Show-UsedMonitors -M $mon -UM $usedMon
Write-Host "`n==================================================================" -ForegroundColor Cyan
Write-Host "Analyse terminee" -ForegroundColor Cyan