Ajout initial du script IPv6ManagerCLI et de sa documentation"

This commit is contained in:
2026-07-31 09:55:47 +02:00
commit 04b9e4f1d1
3 changed files with 812 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
plan/
.claude
.idea/
*.csv
*.log
+386
View File
@@ -0,0 +1,386 @@
<#
.SYNOPSIS
CLI d'activation/desactivation IPv6 pour automates Distech Controls Eclypse Facilities (API v2).
.DESCRIPTION
IPv6ManagerCLI active ou desactive l'IPv6 sur toutes les interfaces reseau
IPv6-capables (secondary, auxiliary, wireless, bridge, primary...) de chaque
automate Distech Controls Eclypse Facilities liste dans un CSV d'entree.
Pour chaque automate :
1. GET /api/rest/v2/services/platform/network/interfaces - recupere la liste des interfaces
2. Filtre les interfaces possedant une section "ipv6" (peu importe son contenu)
3. POST /api/rest/v2/services/platform/network/interfaces/{name}/ipv6 avec {"enabled": true|false}
pour chaque interface IPv6-capable detectee
Compatible uniquement avec les automates Eclypse Facilities supportant l'API v2
(pas de fallback API v1).
.PARAMETER Action
Etat IPv6 a appliquer sur toutes les interfaces IPv6-capables detectees :
Enable - Active l'IPv6
Disable - Desactive l'IPv6 (defaut)
.PARAMETER CsvInput
Chemin vers le fichier CSV d'entree (separateur point-virgule).
Colonnes obligatoires : Hostname, Current Ip, HttpPort, HttpsPort.
Colonnes optionnelles : Username, Password (surchargent -Username/-Password).
.PARAMETER Username
Nom d'utilisateur pour l'authentification API (defaut: admin).
Peut etre surcharge par la colonne Username du CSV.
.PARAMETER Password
Mot de passe pour l'authentification API (defaut: vide).
Peut etre surcharge par la colonne Password du CSV.
.EXAMPLE
.\IPv6ManagerCLI.ps1 -Action Disable -CsvInput ".\automates.csv"
Desactive l'IPv6 sur toutes les interfaces IPv6-capables de chaque automate du CSV.
.EXAMPLE
.\IPv6ManagerCLI.ps1 -Action Enable -CsvInput ".\automates.csv" -Password "MonMotDePasse"
Active l'IPv6 sur toutes les interfaces IPv6-capables de chaque automate du CSV.
.NOTES
Prerequis : PowerShell 5.1+ (inclus dans Windows 10/11)
API : Distech Controls Eclypse Facilities REST API v2 uniquement
(platform/network/interfaces) - pas de fallback v1
Securite : TLS 1.0/1.1/1.2, certificats auto-signes acceptes
#>
param(
[ValidateSet("Enable", "Disable")]
[string]$Action = "Disable",
[Parameter(Mandatory)]
[string]$CsvInput,
[string]$Username = "admin",
[string]$Password = ""
)
# Performance : desactiver la barre de progression Invoke-WebRequest
$ProgressPreference = 'SilentlyContinue'
# =====================================================================
# UTILITAIRES
# =====================================================================
$script:LogFilePath = Join-Path (Get-Location) "IPv6ManagerCLI_$(Get-Date -Format 'yyyy-MM-dd_HH-mm').log"
function Write-Log {
param(
[string]$Message,
[ValidateSet("INFO", "WARN", "ERROR", "OK")]
[string]$Level = "INFO"
)
$ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$tag = switch ($Level) { "INFO" {"[INFO ]"} "WARN" {"[WARN ]"} "ERROR" {"[ERR ]"} "OK" {"[ OK ]"} }
$color = switch ($Level) { "INFO" {"Cyan"} "WARN" {"Yellow"} "ERROR" {"Red"} "OK" {"Green"} }
Write-Host "$ts $tag $Message" -ForegroundColor $color
Add-Content -Path $script:LogFilePath -Value "$ts $tag $Message" -Encoding UTF8
}
# =====================================================================
# FONCTION : Initialize-ApiClient
# Force TLS 1.2 et accepte les certificats auto-signes (equivalent curl -k)
# =====================================================================
$script:CurlAvailable = $false
function Initialize-ApiClient {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls
if (-not ([System.Management.Automation.PSTypeName]'TrustAllCertsPolicy').Type) {
Add-Type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
}
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$script:CurlAvailable = [bool](Get-Command curl.exe -ErrorAction SilentlyContinue)
}
function Test-SslError {
param([System.Exception]$Exception)
$msg = $Exception.Message
return ($msg -match "SSL" -or $msg -match "TLS" -or $msg -match "confiance" -or $msg -match "trust" -or $msg -match "certificate" -or $msg -match "envoi")
}
function Invoke-CurlGet {
param(
[string]$Url,
[string]$Username,
[AllowEmptyString()][string]$Password
)
$output = & curl.exe -s -k -u "${Username}:${Password}" -H "Accept: application/json" $Url 2>&1
if ($LASTEXITCODE -ne 0) {
throw "curl GET erreur (exit code $LASTEXITCODE): $output"
}
return ($output | Out-String)
}
function Invoke-CurlPost {
param(
[string]$Url,
[string]$Username,
[AllowEmptyString()][string]$Password,
[string]$BodyJson
)
$output = & curl.exe -s -k -u "${Username}:${Password}" -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d $BodyJson $Url 2>&1
if ($LASTEXITCODE -ne 0) {
throw "curl POST erreur (exit code $LASTEXITCODE): $output"
}
return ($output | Out-String)
}
# =====================================================================
# FONCTION : Read-AutomateCsv
# =====================================================================
function Read-AutomateCsv {
param([string]$CsvPath)
if (-not (Test-Path $CsvPath)) {
throw "Fichier CSV introuvable : $CsvPath"
}
$rows = @(Import-Csv -Path $CsvPath -Delimiter ";" -Encoding UTF8)
if ($rows.Count -eq 0) {
throw "Fichier CSV vide : $CsvPath"
}
Write-Log -Message "CSV charge : $($rows.Count) ligne(s) depuis $CsvPath" -Level INFO
return $rows
}
# =====================================================================
# FONCTION : Get-BaseUrl
# HTTPS priorise sur HTTP, automate ignore si aucun port valide
# =====================================================================
function Get-BaseUrl {
param([PSCustomObject]$Automate)
$ip = $Automate."Current Ip"
$httpsPort = $Automate.HttpsPort
$httpPort = $Automate.HttpPort
if ($httpsPort -and $httpsPort -ne "" -and [int]$httpsPort -gt 0 -and [int]$httpsPort -ne -1) {
if ([int]$httpsPort -eq 443) { return "https://$ip" }
return "https://${ip}:$httpsPort"
}
if ($httpPort -and $httpPort -ne "" -and [int]$httpPort -gt 0 -and [int]$httpPort -ne -1) {
if ([int]$httpPort -eq 80) { return "http://$ip" }
return "http://${ip}:$httpPort"
}
return $null
}
# =====================================================================
# FONCTION : Get-Credentials
# Identifiants CSV prioritaires sur les parametres globaux
# =====================================================================
function Get-Credentials {
param(
[PSCustomObject]$Automate,
[string]$DefaultUsername,
[string]$DefaultPassword
)
$username = $DefaultUsername
$password = $DefaultPassword
if ($Automate.Username -and $Automate.Username -ne "") { $username = $Automate.Username }
if ($Automate.Password -and $Automate.Password -ne "") { $password = $Automate.Password }
return @{ Username = $username; Password = $password }
}
function Get-AuthHeader {
param(
[string]$Username,
[AllowEmptyString()][string]$Password
)
$pair = "${Username}:${Password}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
return @{
"Authorization" = "Basic $base64"
"Accept" = "application/json"
}
}
# =====================================================================
# FONCTIONS : API v2 - interfaces reseau IPv6
# =====================================================================
function Get-NetworkInterfacesUrl {
param([string]$BaseUrl)
return "$BaseUrl/api/rest/v2/services/platform/network/interfaces"
}
function Get-InterfaceIpv6Url {
param([string]$BaseUrl, [string]$InterfaceName)
return "$BaseUrl/api/rest/v2/services/platform/network/interfaces/$InterfaceName/ipv6"
}
function Invoke-NetworkInterfacesGet {
param(
[string]$Url,
[string]$Username,
[AllowEmptyString()][string]$Password
)
$headers = Get-AuthHeader -Username $Username -Password $Password
try {
$response = Invoke-WebRequest -Uri $Url -Method GET -Headers $headers -UseBasicParsing -TimeoutSec 30
return $response.Content
}
catch {
if ((Test-SslError -Exception $_.Exception) -and $script:CurlAvailable) {
Write-Log -Message "Bascule sur curl.exe -k (echec TLS .NET)" -Level WARN
return Invoke-CurlGet -Url $Url -Username $Username -Password $Password
}
throw
}
}
function Invoke-InterfaceIpv6Post {
param(
[string]$Url,
[string]$Username,
[AllowEmptyString()][string]$Password,
[bool]$Enabled
)
$headers = Get-AuthHeader -Username $Username -Password $Password
$bodyJson = (@{ enabled = $Enabled } | ConvertTo-Json -Compress)
try {
Invoke-WebRequest -Uri $Url -Method POST -Headers $headers -ContentType "application/json" -Body $bodyJson -UseBasicParsing -TimeoutSec 30 | Out-Null
}
catch {
if ((Test-SslError -Exception $_.Exception) -and $script:CurlAvailable) {
Write-Log -Message "Bascule sur curl.exe -k (echec TLS .NET)" -Level WARN
Invoke-CurlPost -Url $Url -Username $Username -Password $Password -BodyJson $bodyJson | Out-Null
return
}
throw
}
}
function Get-Ipv6CapableInterfaces {
param([PSCustomObject]$InterfacesObject)
$result = @()
foreach ($prop in $InterfacesObject.PSObject.Properties) {
if ($prop.Value.PSObject.Properties.Name -contains "ipv6") {
$result += [PSCustomObject]@{
Name = $prop.Name
OldState = $prop.Value.ipv6.enabled
}
}
}
return $result
}
# =====================================================================
# INITIALISATION
# =====================================================================
Initialize-ApiClient
Write-Log -Message "=== IPv6ManagerCLI demarre - Action: $Action ===" -Level INFO
$automates = Read-AutomateCsv -CsvPath $CsvInput
$desiredState = ($Action -eq "Enable")
$statsAutomates = 0
$statsInterfacesOk = 0
$statsInterfacesError = 0
$resultRows = @()
# =====================================================================
# TRAITEMENT DE CHAQUE AUTOMATE
# =====================================================================
foreach ($automate in $automates) {
$hostname = $automate.Hostname
$ip = $automate."Current Ip"
$statsAutomates++
$baseUrl = Get-BaseUrl -Automate $automate
if (-not $baseUrl) {
Write-Log -Message "[$hostname] Aucun port HTTP/HTTPS valide - ignore" -Level WARN
$resultRows += [PSCustomObject]@{
Hostname = $hostname; IP = $ip; Interface = ""
AncienEtat = ""; NouvelEtat = ""
Statut = "Erreur"; Message = "Aucun port HTTP/HTTPS valide"
}
continue
}
$creds = Get-Credentials -Automate $automate -DefaultUsername $Username -DefaultPassword $Password
try {
$interfacesUrl = Get-NetworkInterfacesUrl -BaseUrl $baseUrl
Write-Log -Message "[$hostname] GET $interfacesUrl (user: $($creds.Username))" -Level INFO
$content = Invoke-NetworkInterfacesGet -Url $interfacesUrl -Username $creds.Username -Password $creds.Password
$interfaces = $content | ConvertFrom-Json
$capableInterfaces = Get-Ipv6CapableInterfaces -InterfacesObject $interfaces
Write-Log -Message "[$hostname] $($capableInterfaces.Count) interface(s) IPv6-capable(s) detectee(s)" -Level INFO
foreach ($iface in $capableInterfaces) {
$ipv6Url = Get-InterfaceIpv6Url -BaseUrl $baseUrl -InterfaceName $iface.Name
try {
Write-Log -Message "[$hostname] POST $ipv6Url (enabled=$desiredState)" -Level INFO
Invoke-InterfaceIpv6Post -Url $ipv6Url -Username $creds.Username -Password $creds.Password -Enabled $desiredState
Write-Log -Message "[$hostname] Interface '$($iface.Name)' IPv6 -> $Action" -Level OK
$statsInterfacesOk++
$resultRows += [PSCustomObject]@{
Hostname = $hostname; IP = $ip; Interface = $iface.Name
AncienEtat = $iface.OldState; NouvelEtat = $desiredState
Statut = "Succes"; Message = ""
}
}
catch {
Write-Log -Message "[$hostname] ERREUR interface '$($iface.Name)' : $($_.Exception.Message)" -Level ERROR
$statsInterfacesError++
$resultRows += [PSCustomObject]@{
Hostname = $hostname; IP = $ip; Interface = $iface.Name
AncienEtat = $iface.OldState; NouvelEtat = $desiredState
Statut = "Erreur"; Message = $_.Exception.Message
}
}
}
}
catch {
Write-Log -Message "[$hostname] ERREUR : $($_.Exception.Message)" -Level ERROR
$resultRows += [PSCustomObject]@{
Hostname = $hostname; IP = $ip; Interface = ""
AncienEtat = ""; NouvelEtat = ""
Statut = "Erreur"; Message = $_.Exception.Message
}
}
}
# =====================================================================
# ECRITURE DU CSV DE RESULTAT
# =====================================================================
$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm"
$outputFile = Join-Path (Get-Location) "ipv6manager_$timestamp.csv"
if ($resultRows.Count -gt 0) {
$resultRows | Export-Csv -Path $outputFile -NoTypeInformation -Encoding UTF8 -Delimiter ";"
Write-Log -Message "CSV de resultat ecrit : $outputFile ($($resultRows.Count) ligne(s))" -Level OK
}
else {
Write-Log -Message "Aucune donnee a ecrire dans le CSV de resultat" -Level WARN
}
# =====================================================================
# RESUME FINAL
# =====================================================================
Write-Log -Message "========== RESUME ==========" -Level INFO
Write-Log -Message "Automates traites : $statsAutomates" -Level INFO
Write-Log -Message "Interfaces modifiees avec succes : $statsInterfacesOk" -Level INFO
Write-Log -Message "Interfaces en erreur : $statsInterfacesError" -Level $(if ($statsInterfacesError -gt 0) { "WARN" } else { "INFO" })
Write-Log -Message "============================" -Level INFO
+421
View File
@@ -0,0 +1,421 @@
<!-- FR -->
# IPv6ManagerCLI
Outil en ligne de commande pour activer ou désactiver l'IPv6 sur les interfaces réseau des automates **Distech Controls Eclypse Facilities** (API v2 uniquement), via leur API REST.
---
> **IMPORTANT : Ce projet est un développement personnel indépendant.**
>
> Ce projet a été développé par Charles-Arthur DAVID à titre personnel.
> Distech Controls n'est pas responsable de ce projet et ne le supporte pas.
> Aucune demande de support ne sera prise en charge par Distech Controls.
> Distech Controls ne fournit aucune garantie ni assistance technique pour ce projet.
---
## Prérequis
- **Windows 10 ou 11** (PowerShell 5.1 est inclus par défaut, rien à installer)
- Un accès réseau aux automates Eclypse Facilities
- Les identifiants de connexion aux automates (par défaut : `admin` / mot de passe vide)
- Automates compatibles **API v2** (Eclypse Facilities).
## Ce que fait cet outil
Pour chaque automate listé dans un CSV :
1. Récupère la liste des interfaces réseau (`GET /api/rest/v2/services/platform/network/interfaces`).
2. Détecte les interfaces IPv6-capables : celles possédant une section `ipv6` dans leur configuration (ex : `secondary`, `auxiliary`, `wireless`, `bridge`, `primary`).
3. Applique l'état demandé (`Enable` ou `Disable`) sur **chacune** de ces interfaces (`POST /api/rest/v2/services/platform/network/interfaces/{name}/ipv6` avec `{"enabled": true|false}`), indépendamment de leur état actuel.
En cas d'erreur sur un automate ou une interface (injoignable, échec du POST...), le script logue l'erreur, marque la ligne concernée en erreur, et continue avec l'interface/l'automate suivant.
Un CSV récapitulatif est généré à la fin, avec l'ancien et le nouvel état de chaque interface traitée.
---
## Utilisation avec cadMasterCLI
Ce script peut être piloté depuis **[cadMasterCLI](https://git.cadjou.net/DistechControls/cadMasterCLI)**, qui évite d'avoir à utiliser PowerShell manuellement.
Quand ce script est sélectionné dans cadMasterCLI :
- Les paramètres sont détectés automatiquement et affichés sous forme de champs :
- `Action` : RadioButtons `Enable` / `Disable` (valeurs du `[ValidateSet]`, `Disable` sélectionné par défaut)
- `CsvInput` : bouton "Parcourir" + zone de collage d'IPs (conversion automatique en CSV)
- `Username`, `Password` : champs texte
- Il suffit de renseigner les champs puis de lancer l'exécution depuis l'interface — aucune commande PowerShell à taper, aucune politique d'exécution à modifier manuellement.
Se référer à la section suivante pour le détail des paramètres, du format du CSV attendu et du dépannage.
---
## Utilisation en autonome
### Vérifier que PowerShell est disponible
Ouvrir un terminal (touche `Windows` + `R`, taper `powershell`, puis `Entrée`) et taper :
```powershell
$PSVersionTable.PSVersion
```
Le numéro `Major` doit être **5 ou plus**.
### Installation
Aucune installation requise. Télécharger ou cloner le dépôt :
```
IPv6ManagerCLI/ (ce dépôt)
├── IPv6ManagerCLI.ps1 <- Script principal
└── README.md
```
### Utilisation
#### Ouvrir PowerShell dans le bon dossier
1. Ouvrir l'explorateur de fichiers et naviguer dans le dossier du dépôt
2. Cliquer dans la barre d'adresse, taper `powershell`, puis appuyer sur `Entrée`
Ou bien dans un terminal PowerShell :
```powershell
cd "C:\chemin\vers\IPv6ManagerCLI"
```
#### Politique d'exécution
Si c'est la première fois, PowerShell peut bloquer l'exécution des scripts. Autoriser pour la session en cours :
```powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
```
Cette commande est sans risque : elle n'autorise les scripts que pour la fenêtre PowerShell en cours.
#### Désactiver l'IPv6 (action par défaut)
```powershell
.\IPv6ManagerCLI.ps1 -CsvInput ".\automates.csv"
```
#### Activer l'IPv6
```powershell
.\IPv6ManagerCLI.ps1 -Action Enable -CsvInput ".\automates.csv"
```
Avec un mot de passe :
```powershell
.\IPv6ManagerCLI.ps1 -Action Enable -CsvInput ".\automates.csv" -Password "MonMotDePasse"
```
**Résultat** : Un fichier `ipv6manager_yyyy-MM-dd_HH-mm.csv` est créé dans le dossier courant, avec le détail par interface (ancien état, nouvel état, statut).
#### Aide intégrée
```powershell
Get-Help .\IPv6ManagerCLI.ps1 -Detailed
```
### Format du CSV d'entrée
Le fichier CSV utilise le **point-virgule** (`;`) comme séparateur.
#### Colonnes obligatoires
| Colonne | Description |
|---------|-------------|
| `Hostname` | Nom de l'automate |
| `Current Ip` | Adresse IP de l'automate |
| `HttpPort` | Port HTTP (`80` ou `-1` si désactivé) |
| `HttpsPort` | Port HTTPS (`443` ou `-1` si désactivé) |
#### Colonnes optionnelles
| Colonne | Description |
|---------|-------------|
| `Username` | Login spécifique à cet automate |
| `Password` | Mot de passe spécifique à cet automate |
#### Exemple de CSV
```csv
"Hostname";"Current Ip";"HttpPort";"HttpsPort"
"ECY-BATIMENT-01";"10.60.105.42";"-1";"443"
"ECY-BATIMENT-02";"10.60.105.44";"-1";"443"
```
### CSV de résultat
Un fichier `ipv6manager_yyyy-MM-dd_HH-mm.csv` est généré dans le dossier courant, avec une ligne par interface traitée :
| Colonne | Description |
|---------|-------------|
| `Hostname` | Nom de l'automate |
| `IP` | Adresse IP de l'automate |
| `Interface` | Nom de l'interface (secondary, auxiliary, wireless, bridge, primary...) |
| `AncienEtat` | État IPv6 avant modification (`True`/`False`) |
| `NouvelEtat` | État IPv6 appliqué (`True`/`False`) |
| `Statut` | `Succes` ou `Erreur` |
| `Message` | Détail de l'erreur si applicable |
### Logs
Chaque exécution affiche sa progression directement dans la console, avec un résumé final (automates traités, interfaces modifiées, interfaces en erreur).
#### Niveaux de log
| Niveau | Couleur console | Signification |
|--------|----------------|---------------|
| `INFO` | Cyan | Opération normale |
| `OK` | Vert | Opération réussie |
| `WARN` | Jaune | Avertissement (port invalide...) |
| `ERROR` | Rouge | Erreur (connexion échouée, automate injoignable...) |
### Résumé des paramètres
```
.\IPv6ManagerCLI.ps1 [-Action <Enable|Disable>] -CsvInput <chemin> [-Username <login>] [-Password <mdp>]
```
| Paramètre | Obligatoire | Défaut | Description |
|-----------|:-----------:|--------|-------------|
| `-Action` | Non | `Disable` | `Enable` ou `Disable` |
| `-CsvInput` | Oui | — | Chemin du fichier CSV d'entrée |
| `-Username` | Non | `admin` | Login API (surchargeable par le CSV) |
| `-Password` | Non | *(vide)* | Mot de passe API (surchargeable par le CSV) |
### Dépannage
#### "Impossible d'exécuter le script car l'exécution de scripts est désactivée"
```powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
```
#### "Aucun port HTTP/HTTPS valide"
Vérifier que les colonnes `HttpPort` et `HttpsPort` du CSV contiennent des valeurs valides. Un port à `-1` signifie "désactivé". Au moins un des deux doit être actif.
#### Timeout ou erreur de connexion
- Vérifier que l'automate est joignable (`ping 10.60.105.x`)
- Vérifier les identifiants (Username / Password)
- Vérifier que le port est correct (HTTP 80 ou HTTPS 443)
- Vérifier que l'automate est bien un Eclypse Facilities compatible API v2
<!-- EN -->
# IPv6ManagerCLI
Command-line tool to enable or disable IPv6 on the network interfaces of **Distech Controls Eclypse Facilities** controllers (API v2 only), via their REST API.
---
> **IMPORTANT: This project is an independent personal development.**
>
> This project was developed by Charles-Arthur DAVID on a personal basis.
> Distech Controls is not responsible for this project and does not support it.
> No support requests will be handled by Distech Controls.
> Distech Controls provides no warranty or technical assistance for this project.
---
## Prerequisites
- **Windows 10 or 11** (PowerShell 5.1 is included by default, nothing to install)
- Network access to the Eclypse Facilities controllers
- Login credentials for the controllers (default: `admin` / empty password)
- Controllers compatible with **API v2** (Eclypse Facilities).
## What this tool does
For each controller listed in a CSV:
1. Retrieves the list of network interfaces (`GET /api/rest/v2/services/platform/network/interfaces`).
2. Detects IPv6-capable interfaces: those with an `ipv6` section in their configuration (e.g. `secondary`, `auxiliary`, `wireless`, `bridge`, `primary`).
3. Applies the requested state (`Enable` or `Disable`) on **each** of these interfaces (`POST /api/rest/v2/services/platform/network/interfaces/{name}/ipv6` with `{"enabled": true|false}`), regardless of their current state.
On error for a controller or interface (unreachable, failed POST...), the script logs the error, flags the row as an error, and continues with the next interface/controller.
A summary CSV is generated at the end, with the old and new state of each processed interface.
---
## Using with cadMasterCLI
This script can be run from **[cadMasterCLI](https://git.cadjou.net/DistechControls/cadMasterCLI)**, which avoids having to use PowerShell manually.
When this script is selected in cadMasterCLI:
- Parameters are detected automatically and rendered as input fields:
- `Action`: RadioButtons `Enable` / `Disable` (values from `[ValidateSet]`, `Disable` selected by default)
- `CsvInput`: a "Browse" button plus an IP paste area (automatic conversion to CSV)
- `Username`, `Password`: text fields
- Simply fill in the fields and launch the run from the interface — no PowerShell command to type, no execution policy to change manually.
See the next section for parameter details, the expected CSV format, and troubleshooting.
---
## Standalone usage
### Check that PowerShell is available
Open a terminal (`Windows` key + `R`, type `powershell`, then `Enter`) and type:
```powershell
$PSVersionTable.PSVersion
```
The `Major` number must be **5 or higher**.
### Installation
No installation required. Download or clone this repository:
```
IPv6ManagerCLI/ (this repo)
├── IPv6ManagerCLI.ps1 <- Main script
└── README.md
```
### Usage
#### Open PowerShell in the right folder
1. Open File Explorer and navigate to the repository folder
2. Click in the address bar, type `powershell`, then press `Enter`
Or in a PowerShell terminal:
```powershell
cd "C:\path\to\IPv6ManagerCLI"
```
#### Execution policy
The first time, PowerShell may block script execution. Allow it for the current session:
```powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
```
This command is safe: it only allows scripts for the current PowerShell window.
#### Disable IPv6 (default action)
```powershell
.\IPv6ManagerCLI.ps1 -CsvInput ".\controllers.csv"
```
#### Enable IPv6
```powershell
.\IPv6ManagerCLI.ps1 -Action Enable -CsvInput ".\controllers.csv"
```
With a password:
```powershell
.\IPv6ManagerCLI.ps1 -Action Enable -CsvInput ".\controllers.csv" -Password "MyPassword"
```
**Result**: A file `ipv6manager_yyyy-MM-dd_HH-mm.csv` is created in the current folder, with per-interface detail (old state, new state, status).
#### Built-in help
```powershell
Get-Help .\IPv6ManagerCLI.ps1 -Detailed
```
### Input CSV format
The CSV file uses a **semicolon** (`;`) as separator.
#### Required columns
| Column | Description |
|---------|-------------|
| `Hostname` | Controller name |
| `Current Ip` | Controller IP address |
| `HttpPort` | HTTP port (`80` or `-1` if disabled) |
| `HttpsPort` | HTTPS port (`443` or `-1` if disabled) |
#### Optional columns
| Column | Description |
|---------|-------------|
| `Username` | Login specific to this controller |
| `Password` | Password specific to this controller |
#### CSV example
```csv
"Hostname";"Current Ip";"HttpPort";"HttpsPort"
"ECY-BUILDING-01";"10.60.105.42";"-1";"443"
"ECY-BUILDING-02";"10.60.105.44";"-1";"443"
```
### Result CSV
A file `ipv6manager_yyyy-MM-dd_HH-mm.csv` is generated in the current folder, with one row per processed interface:
| Column | Description |
|---------|-------------|
| `Hostname` | Controller name |
| `IP` | Controller IP address |
| `Interface` | Interface name (secondary, auxiliary, wireless, bridge, primary...) |
| `AncienEtat` | IPv6 state before the change (`True`/`False`) |
| `NouvelEtat` | Applied IPv6 state (`True`/`False`) |
| `Statut` | `Succes` or `Erreur` |
| `Message` | Error detail if applicable |
### Logs
Each run displays its progress directly in the console, with a final summary (controllers processed, interfaces changed, interfaces in error).
#### Log levels
| Level | Console color | Meaning |
|--------|----------------|---------------|
| `INFO` | Cyan | Normal operation |
| `OK` | Green | Successful operation |
| `WARN` | Yellow | Warning (invalid port...) |
| `ERROR` | Red | Error (connection failed, controller unreachable...) |
### Parameters summary
```
.\IPv6ManagerCLI.ps1 [-Action <Enable|Disable>] -CsvInput <path> [-Username <login>] [-Password <password>]
```
| Parameter | Required | Default | Description |
|-----------|:-----------:|--------|-------------|
| `-Action` | No | `Disable` | `Enable` or `Disable` |
| `-CsvInput` | Yes | — | Path to the input CSV file |
| `-Username` | No | `admin` | API login (overridable by the CSV) |
| `-Password` | No | *(empty)* | API password (overridable by the CSV) |
### Troubleshooting
#### "Cannot run the script because script execution is disabled"
```powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
```
#### "No valid HTTP/HTTPS port"
Check that the CSV's `HttpPort` and `HttpsPort` columns contain valid values. A port set to `-1` means "disabled". At least one of the two must be active.
#### Timeout or connection error
- Check that the controller is reachable (`ping 10.60.105.x`)
- Check the credentials (Username / Password)
- Check that the port is correct (HTTP 80 or HTTPS 443)
- Check that the controller is an Eclypse Facilities unit compatible with API v2