Ajout du script AuditLogCLI
- Script principal : AuditLogCLI.ps1 (310 lignes) — conversion PowerShell de auditLog.bat, export des journaux d'audit Distech Eclypse via API REST, compatible cadMasterCLI - Documentation : README.md (437 lignes) — bilingue FR/EN (<!-- FR -->/<!-- EN -->), compatible affichage cadMasterCLI
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
plan
|
||||||
|
.claude
|
||||||
+310
@@ -0,0 +1,310 @@
|
|||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
CLI d'export des journaux d'audit pour automates Distech Controls Eclypse.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
AuditLogCLI recupere les journaux d'audit (audit-logs) de chaque automate
|
||||||
|
Distech Controls Eclypse liste dans un CSV d'entree, via leur API REST,
|
||||||
|
et les enregistre au format CSV (un fichier par automate, ou un fichier
|
||||||
|
consolide unique).
|
||||||
|
|
||||||
|
.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.
|
||||||
|
|
||||||
|
.PARAMETER StartDate
|
||||||
|
Date de debut (format yyyy-MM-dd) pour filtrer les journaux d'audit. Optionnel.
|
||||||
|
|
||||||
|
.PARAMETER EndDate
|
||||||
|
Date de fin (format yyyy-MM-dd) pour filtrer les journaux d'audit. Optionnel.
|
||||||
|
|
||||||
|
.PARAMETER OutputFormat
|
||||||
|
Format de sortie :
|
||||||
|
PerAutomate - Un fichier CSV brut par automate, dans un dossier horodate (defaut)
|
||||||
|
Consolidated - Un seul fichier CSV avec toutes les lignes, colonnes Hostname/IP ajoutees
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput ".\automates.csv"
|
||||||
|
|
||||||
|
Recupere les journaux d'audit de tous les automates listes dans le CSV.
|
||||||
|
Genere un fichier CSV par automate dans un dossier Audit_yyyy-MM-dd_HH-mm.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput ".\automates.csv" -OutputFormat Consolidated -StartDate 2026-01-01 -EndDate 2026-07-09
|
||||||
|
|
||||||
|
Recupere les journaux d'audit filtres sur la periode donnee et les
|
||||||
|
consolide dans un seul fichier CSV.
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Prerequis : PowerShell 5.1+ (inclus dans Windows 10/11)
|
||||||
|
API : Distech Controls Eclypse REST API v1
|
||||||
|
Securite : TLS 1.2, certificats auto-signes acceptes
|
||||||
|
Important : les noms de query params "startDate"/"endDate" sont une
|
||||||
|
hypothese non validee contre la documentation officielle de
|
||||||
|
l'API audit-logs. A verifier avant utilisation en production.
|
||||||
|
#>
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[string]$CsvInput,
|
||||||
|
|
||||||
|
[string]$Username = "admin",
|
||||||
|
|
||||||
|
[string]$Password = "",
|
||||||
|
|
||||||
|
[string]$StartDate,
|
||||||
|
|
||||||
|
[string]$EndDate,
|
||||||
|
|
||||||
|
[ValidateSet("PerAutomate", "Consolidated")]
|
||||||
|
[string]$OutputFormat = "PerAutomate"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Performance : desactiver la barre de progression Invoke-WebRequest
|
||||||
|
$ProgressPreference = 'SilentlyContinue'
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# UTILITAIRES
|
||||||
|
# =====================================================================
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# FONCTION : Initialize-ApiClient
|
||||||
|
# Force TLS 1.2 et accepte les certificats auto-signes (equivalent curl -k)
|
||||||
|
# =====================================================================
|
||||||
|
function Initialize-ApiClient {
|
||||||
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# 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" = "text/csv, application/json, text/plain, */*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-AuditLogUrl {
|
||||||
|
param(
|
||||||
|
[string]$BaseUrl,
|
||||||
|
[string]$StartDate,
|
||||||
|
[string]$EndDate
|
||||||
|
)
|
||||||
|
$url = "$BaseUrl/api/rest/v1/system/audit-logs"
|
||||||
|
$queryParams = @()
|
||||||
|
if ($StartDate) { $queryParams += "startDate=$StartDate" }
|
||||||
|
if ($EndDate) { $queryParams += "endDate=$EndDate" }
|
||||||
|
if ($queryParams.Count -gt 0) { $url += "?" + ($queryParams -join "&") }
|
||||||
|
return $url
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-AuditLogGet {
|
||||||
|
param(
|
||||||
|
[string]$Url,
|
||||||
|
[string]$Username,
|
||||||
|
[AllowEmptyString()][string]$Password
|
||||||
|
)
|
||||||
|
$headers = Get-AuthHeader -Username $Username -Password $Password
|
||||||
|
return Invoke-WebRequest -Uri $Url -Method GET -Headers $headers -UseBasicParsing -TimeoutSec 30
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# VALIDATION DES PARAMETRES DE DATE
|
||||||
|
# =====================================================================
|
||||||
|
foreach ($dateParam in @(
|
||||||
|
@{ Name = "StartDate"; Value = $StartDate },
|
||||||
|
@{ Name = "EndDate"; Value = $EndDate }
|
||||||
|
)) {
|
||||||
|
if ($dateParam.Value) {
|
||||||
|
$parsed = [DateTime]::MinValue
|
||||||
|
if (-not [DateTime]::TryParseExact($dateParam.Value, "yyyy-MM-dd", $null, [System.Globalization.DateTimeStyles]::None, [ref]$parsed)) {
|
||||||
|
throw "Parametre -$($dateParam.Name) invalide : '$($dateParam.Value)' (format attendu : yyyy-MM-dd)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# INITIALISATION
|
||||||
|
# =====================================================================
|
||||||
|
Initialize-ApiClient
|
||||||
|
Write-Log -Message "=== AuditLogCLI demarre - OutputFormat: $OutputFormat ===" -Level INFO
|
||||||
|
|
||||||
|
$automates = Read-AutomateCsv -CsvPath $CsvInput
|
||||||
|
|
||||||
|
$statsTotal = 0
|
||||||
|
$statsError = 0
|
||||||
|
$consolidatedRows = @()
|
||||||
|
$outputDir = $null
|
||||||
|
|
||||||
|
if ($OutputFormat -eq "PerAutomate") {
|
||||||
|
$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm"
|
||||||
|
$outputDir = Join-Path (Get-Location) "Audit_$timestamp"
|
||||||
|
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
|
||||||
|
Write-Log -Message "Dossier de sortie : $outputDir" -Level INFO
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# TRAITEMENT DE CHAQUE AUTOMATE
|
||||||
|
# =====================================================================
|
||||||
|
foreach ($automate in $automates) {
|
||||||
|
$hostname = $automate.Hostname
|
||||||
|
$ip = $automate."Current Ip"
|
||||||
|
$statsTotal++
|
||||||
|
|
||||||
|
try {
|
||||||
|
$baseUrl = Get-BaseUrl -Automate $automate
|
||||||
|
if (-not $baseUrl) {
|
||||||
|
Write-Log -Message "[$hostname] Aucun port HTTP/HTTPS valide - ignore" -Level WARN
|
||||||
|
$statsError++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$creds = Get-Credentials -Automate $automate -DefaultUsername $Username -DefaultPassword $Password
|
||||||
|
$url = Get-AuditLogUrl -BaseUrl $baseUrl -StartDate $StartDate -EndDate $EndDate
|
||||||
|
|
||||||
|
Write-Log -Message "[$hostname] GET $url (user: $($creds.Username))" -Level INFO
|
||||||
|
|
||||||
|
$response = Invoke-AuditLogGet -Url $url -Username $creds.Username -Password $creds.Password
|
||||||
|
|
||||||
|
if ($OutputFormat -eq "PerAutomate") {
|
||||||
|
$filePath = Join-Path $outputDir "$ip.csv"
|
||||||
|
Set-Content -Path $filePath -Value $response.Content -Encoding UTF8
|
||||||
|
Write-Log -Message "[$hostname] Journal d'audit ecrit : $filePath" -Level OK
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Suppose une reponse API au format CSV (comme le .bat d'origine qui
|
||||||
|
# ecrit directement la reponse brute dans un fichier .csv)
|
||||||
|
$rows = @($response.Content | ConvertFrom-Csv)
|
||||||
|
foreach ($row in $rows) {
|
||||||
|
$obj = [ordered]@{ Hostname = $hostname; IP = $ip }
|
||||||
|
foreach ($prop in $row.PSObject.Properties) { $obj[$prop.Name] = $prop.Value }
|
||||||
|
$consolidatedRows += [PSCustomObject]$obj
|
||||||
|
}
|
||||||
|
Write-Log -Message "[$hostname] $($rows.Count) entree(s) d'audit recuperee(s)" -Level OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Log -Message "[$hostname] ERREUR : $($_.Exception.Message)" -Level ERROR
|
||||||
|
$statsError++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# ECRITURE DE LA SORTIE CONSOLIDEE
|
||||||
|
# =====================================================================
|
||||||
|
if ($OutputFormat -eq "Consolidated") {
|
||||||
|
$timestamp = Get-Date -Format "yyyy-MM-dd_HHhmm"
|
||||||
|
$outputFile = Join-Path (Get-Location) "audit_$timestamp.csv"
|
||||||
|
if ($consolidatedRows.Count -gt 0) {
|
||||||
|
$consolidatedRows | Export-Csv -Path $outputFile -NoTypeInformation -Encoding UTF8
|
||||||
|
Write-Log -Message "CSV consolide ecrit : $outputFile ($($consolidatedRows.Count) ligne(s))" -Level OK
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Log -Message "Aucune donnee a ecrire dans le CSV consolide" -Level WARN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# RESUME FINAL
|
||||||
|
# =====================================================================
|
||||||
|
Write-Log -Message "========== RESUME ==========" -Level INFO
|
||||||
|
Write-Log -Message "Automates traites : $statsTotal" -Level INFO
|
||||||
|
Write-Log -Message "Automates en erreur : $statsError" -Level $(if ($statsError -gt 0) { "WARN" } else { "INFO" })
|
||||||
|
Write-Log -Message "============================" -Level INFO
|
||||||
@@ -0,0 +1,437 @@
|
|||||||
|
<!-- FR -->
|
||||||
|
# AuditLogCLI
|
||||||
|
|
||||||
|
Outil en ligne de commande pour récupérer les journaux d'audit (audit-logs) des automates **Distech Controls Eclypse** 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 (HTTP ou HTTPS)
|
||||||
|
- Les identifiants de connexion aux automates (par défaut : `admin` / mot de passe vide)
|
||||||
|
|
||||||
|
## Ce que fait cet outil
|
||||||
|
|
||||||
|
Se connecte à chaque automate listé dans un CSV, récupère son journal d'audit via l'API REST, et enregistre le résultat au format CSV :
|
||||||
|
|
||||||
|
- **Sortie par automate** (`PerAutomate`, défaut) : un fichier CSV brut par automate, dans un dossier horodaté — reproduit le comportement de l'ancien script `auditLog.bat`.
|
||||||
|
- **Sortie consolidée** (`Consolidated`) : un seul fichier CSV regroupant toutes les lignes de tous les automates, avec les colonnes `Hostname`/`IP` ajoutées.
|
||||||
|
|
||||||
|
Un filtrage optionnel par période (`-StartDate`/`-EndDate`) peut être appliqué à la requête.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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 :
|
||||||
|
|
||||||
|
- Ce `README.md` s'affiche dans le panneau de gauche, dans la langue active de l'interface.
|
||||||
|
- Les paramètres sont détectés automatiquement et affichés sous forme de champs :
|
||||||
|
- `CsvInput` : bouton "Parcourir" + zone de collage d'IPs (conversion automatique en CSV)
|
||||||
|
- `Username`, `Password` : champs texte
|
||||||
|
- `StartDate`, `EndDate` : champs texte (format `yyyy-MM-dd`)
|
||||||
|
- `OutputFormat` : RadioButtons `PerAutomate` / `Consolidated` (valeurs du `[ValidateSet]`)
|
||||||
|
- 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 dossier du projet :
|
||||||
|
|
||||||
|
```
|
||||||
|
ECY-Auditlog/
|
||||||
|
├── AuditLogCLI.ps1 <- Script principal
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Utilisation
|
||||||
|
|
||||||
|
#### Ouvrir PowerShell dans le bon dossier
|
||||||
|
|
||||||
|
1. Ouvrir l'explorateur de fichiers et naviguer dans le dossier `ECY-Auditlog`
|
||||||
|
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\ECY-Auditlog"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 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.
|
||||||
|
|
||||||
|
#### Récupérer les journaux d'audit — sortie par automate
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput ".\automates.csv"
|
||||||
|
```
|
||||||
|
|
||||||
|
Avec un mot de passe :
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput ".\automates.csv" -Password "MonMotDePasse"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Résultat** : Un dossier `Audit_yyyy-MM-dd_HH-mm` est créé dans le dossier courant, avec un fichier `{IP}.csv` par automate.
|
||||||
|
|
||||||
|
#### Récupérer les journaux d'audit — sortie consolidée, avec filtre de période
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput ".\automates.csv" -OutputFormat Consolidated -StartDate 2026-01-01 -EndDate 2026-07-09
|
||||||
|
```
|
||||||
|
|
||||||
|
**Résultat** : Un fichier `audit_yyyy-MM-dd_HHhmm.csv` unique est créé dans le dossier courant, avec toutes les entrées de tous les automates.
|
||||||
|
|
||||||
|
#### Aide intégrée
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Get-Help .\AuditLogCLI.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"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
Chaque exécution affiche sa progression directement dans la console, avec un résumé final (automates traités, automates 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, aucune donnée...) |
|
||||||
|
| `ERROR` | Rouge | Erreur (connexion échouée, automate injoignable...) |
|
||||||
|
|
||||||
|
#### Exemple de log
|
||||||
|
|
||||||
|
```
|
||||||
|
2026-07-09 08:15:02 [INFO ] === AuditLogCLI demarre - OutputFormat: PerAutomate ===
|
||||||
|
2026-07-09 08:15:02 [INFO ] CSV charge : 2 ligne(s) depuis .\automates.csv
|
||||||
|
2026-07-09 08:15:02 [INFO ] Dossier de sortie : .\Audit_2026-07-09_08-15
|
||||||
|
2026-07-09 08:15:02 [INFO ] [ECY-BATIMENT-01] GET https://10.60.105.42/api/rest/v1/system/audit-logs (user: admin)
|
||||||
|
2026-07-09 08:15:03 [ OK ] [ECY-BATIMENT-01] Journal d'audit ecrit : .\Audit_2026-07-09_08-15\10.60.105.42.csv
|
||||||
|
2026-07-09 08:15:03 [INFO ] [ECY-BATIMENT-02] GET https://10.60.105.44/api/rest/v1/system/audit-logs (user: admin)
|
||||||
|
2026-07-09 08:15:04 [ OK ] [ECY-BATIMENT-02] Journal d'audit ecrit : .\Audit_2026-07-09_08-15\10.60.105.44.csv
|
||||||
|
2026-07-09 08:15:04 [INFO ] ========== RESUME ==========
|
||||||
|
2026-07-09 08:15:04 [INFO ] Automates traites : 2
|
||||||
|
2026-07-09 08:15:04 [INFO ] Automates en erreur : 0
|
||||||
|
2026-07-09 08:15:04 [INFO ] ============================
|
||||||
|
```
|
||||||
|
|
||||||
|
### Résumé des paramètres
|
||||||
|
|
||||||
|
```
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput <chemin> [-Username <login>] [-Password <mdp>] [-StartDate <yyyy-MM-dd>] [-EndDate <yyyy-MM-dd>] [-OutputFormat <PerAutomate|Consolidated>]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Paramètre | Obligatoire | Défaut | Description |
|
||||||
|
|-----------|:-----------:|--------|-------------|
|
||||||
|
| `-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) |
|
||||||
|
| `-StartDate` | Non | *(aucun)* | Date de début du filtre (`yyyy-MM-dd`) |
|
||||||
|
| `-EndDate` | Non | *(aucun)* | Date de fin du filtre (`yyyy-MM-dd`) |
|
||||||
|
| `-OutputFormat` | Non | `PerAutomate` | `PerAutomate` ou `Consolidated` |
|
||||||
|
|
||||||
|
### 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)
|
||||||
|
|
||||||
|
#### Le filtre `-StartDate`/`-EndDate` ne semble avoir aucun effet
|
||||||
|
|
||||||
|
Les noms des paramètres de requête (`startDate`/`endDate`) utilisés par ce script sont une hypothèse non validée contre la documentation officielle de l'API `audit-logs`. Si le filtrage ne fonctionne pas, vérifier la documentation de l'API Eclypse de l'automate concerné.
|
||||||
|
|
||||||
|
<!-- EN -->
|
||||||
|
# AuditLogCLI
|
||||||
|
|
||||||
|
Command-line tool to retrieve audit logs from **Distech Controls Eclypse** controllers 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 controllers (HTTP or HTTPS)
|
||||||
|
- Login credentials for the controllers (default: `admin` / empty password)
|
||||||
|
|
||||||
|
## What this tool does
|
||||||
|
|
||||||
|
Connects to each controller listed in a CSV, retrieves its audit log via the REST API, and saves the result as CSV:
|
||||||
|
|
||||||
|
- **Per-controller output** (`PerAutomate`, default): one raw CSV file per controller, in a timestamped folder — reproduces the behavior of the original `auditLog.bat` script.
|
||||||
|
- **Consolidated output** (`Consolidated`): a single CSV file combining all rows from all controllers, with `Hostname`/`IP` columns added.
|
||||||
|
|
||||||
|
An optional date-range filter (`-StartDate`/`-EndDate`) can be applied to the request.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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:
|
||||||
|
|
||||||
|
- This `README.md` is displayed in the left-hand panel, in the interface's active language.
|
||||||
|
- Parameters are detected automatically and rendered as input fields:
|
||||||
|
- `CsvInput`: a "Browse" button plus an IP paste area (automatic conversion to CSV)
|
||||||
|
- `Username`, `Password`: text fields
|
||||||
|
- `StartDate`, `EndDate`: text fields (`yyyy-MM-dd` format)
|
||||||
|
- `OutputFormat`: RadioButtons `PerAutomate` / `Consolidated` (values from `[ValidateSet]`)
|
||||||
|
- 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 the project folder:
|
||||||
|
|
||||||
|
```
|
||||||
|
ECY-Auditlog/
|
||||||
|
├── AuditLogCLI.ps1 <- Main script
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
#### Open PowerShell in the right folder
|
||||||
|
|
||||||
|
1. Open File Explorer and navigate to the `ECY-Auditlog` folder
|
||||||
|
2. Click in the address bar, type `powershell`, then press `Enter`
|
||||||
|
|
||||||
|
Or in a PowerShell terminal:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cd "C:\path\to\ECY-Auditlog"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 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.
|
||||||
|
|
||||||
|
#### Retrieve audit logs — per-controller output
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput ".\controllers.csv"
|
||||||
|
```
|
||||||
|
|
||||||
|
With a password:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput ".\controllers.csv" -Password "MyPassword"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Result**: A folder `Audit_yyyy-MM-dd_HH-mm` is created in the current folder, with one `{IP}.csv` file per controller.
|
||||||
|
|
||||||
|
#### Retrieve audit logs — consolidated output, with date filter
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput ".\controllers.csv" -OutputFormat Consolidated -StartDate 2026-01-01 -EndDate 2026-07-09
|
||||||
|
```
|
||||||
|
|
||||||
|
**Result**: A single `audit_yyyy-MM-dd_HHhmm.csv` file is created in the current folder, with all entries from all controllers.
|
||||||
|
|
||||||
|
#### Built-in help
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Get-Help .\AuditLogCLI.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"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
Each run displays its progress directly in the console, with a final summary (controllers processed, controllers in error).
|
||||||
|
|
||||||
|
#### Log levels
|
||||||
|
|
||||||
|
| Level | Console color | Meaning |
|
||||||
|
|--------|----------------|---------------|
|
||||||
|
| `INFO` | Cyan | Normal operation |
|
||||||
|
| `OK` | Green | Successful operation |
|
||||||
|
| `WARN` | Yellow | Warning (invalid port, no data...) |
|
||||||
|
| `ERROR` | Red | Error (connection failed, controller unreachable...) |
|
||||||
|
|
||||||
|
#### Log example
|
||||||
|
|
||||||
|
```
|
||||||
|
2026-07-09 08:15:02 [INFO ] === AuditLogCLI demarre - OutputFormat: PerAutomate ===
|
||||||
|
2026-07-09 08:15:02 [INFO ] CSV charge : 2 ligne(s) depuis .\automates.csv
|
||||||
|
2026-07-09 08:15:02 [INFO ] Dossier de sortie : .\Audit_2026-07-09_08-15
|
||||||
|
2026-07-09 08:15:02 [INFO ] [ECY-BUILDING-01] GET https://10.60.105.42/api/rest/v1/system/audit-logs (user: admin)
|
||||||
|
2026-07-09 08:15:03 [ OK ] [ECY-BUILDING-01] Journal d'audit ecrit : .\Audit_2026-07-09_08-15\10.60.105.42.csv
|
||||||
|
2026-07-09 08:15:03 [INFO ] [ECY-BUILDING-02] GET https://10.60.105.44/api/rest/v1/system/audit-logs (user: admin)
|
||||||
|
2026-07-09 08:15:04 [ OK ] [ECY-BUILDING-02] Journal d'audit ecrit : .\Audit_2026-07-09_08-15\10.60.105.44.csv
|
||||||
|
2026-07-09 08:15:04 [INFO ] ========== RESUME ==========
|
||||||
|
2026-07-09 08:15:04 [INFO ] Automates traites : 2
|
||||||
|
2026-07-09 08:15:04 [INFO ] Automates en erreur : 0
|
||||||
|
2026-07-09 08:15:04 [INFO ] ============================
|
||||||
|
```
|
||||||
|
|
||||||
|
> Note: log messages are generated by the script in French; the example above is shown as-is.
|
||||||
|
|
||||||
|
### Parameters summary
|
||||||
|
|
||||||
|
```
|
||||||
|
.\AuditLogCLI.ps1 -CsvInput <path> [-Username <login>] [-Password <password>] [-StartDate <yyyy-MM-dd>] [-EndDate <yyyy-MM-dd>] [-OutputFormat <PerAutomate|Consolidated>]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Parameter | Required | Default | Description |
|
||||||
|
|-----------|:-----------:|--------|-------------|
|
||||||
|
| `-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) |
|
||||||
|
| `-StartDate` | No | *(none)* | Filter start date (`yyyy-MM-dd`) |
|
||||||
|
| `-EndDate` | No | *(none)* | Filter end date (`yyyy-MM-dd`) |
|
||||||
|
| `-OutputFormat` | No | `PerAutomate` | `PerAutomate` or `Consolidated` |
|
||||||
|
|
||||||
|
### 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)
|
||||||
|
|
||||||
|
#### The `-StartDate`/`-EndDate` filter seems to have no effect
|
||||||
|
|
||||||
|
The query parameter names (`startDate`/`endDate`) used by this script are an unverified assumption against the official `audit-logs` API documentation. If filtering does not work, check the Eclypse API documentation for the specific controller.
|
||||||
Reference in New Issue
Block a user