feat(deploy): install silencieuse (dashboard) + MAJ GPO clients Léa + procédure Julien — 2026-07-06
Deux canaux de déploiement des clients Léa, en s'appuyant sur l'installeur EXE
v1.0.2 existant (per-user, upgrade-safe, mode /VERYSILENT /CONFIG=).
- Route dashboard `GET /api/fleet/installer` (web_dashboard/app.py, insertion pure,
125 lignes, 0 suppression) : sert un ZIP {EXE + install_silencieux.bat + enroll.txt
(SERVER_URL/token injectés via _resolve_public_server_url) + LISEZMOI} pour un poste
NEUF. L'EXE génère lui-même le machine_id → pas de pré-enregistrement (distinct de
la voie ZIP download_agent_package). Tri EXE en semver (1.0.10 > 1.0.2). Testée e2e.
- deploy/installer/silent/ : lanceur d'install silencieuse + gabarit enroll + notice.
- deploy/gpo/Deploy-LeaUpdate.ps1 : MAJ upgrade-safe via GPO **logon script user-context**
(install per-user invisible au contexte SYSTEM). Détection version = **DisplayVersion
du registre HKCU** (primaire pour install EXE ; le config.txt EXE ne porte PAS la
version — vérifié sur poste réel), fallback RPA_AGENT_VERSION (installs ZIP).
Comparaison semver, idempotent, journalisation best-effort silencieuse, non bloquant
à l'ouverture de session. Options -DryRun / -TargetVersionOverride / -LogShareOverride.
**Validé sur poste réel .11 (Windows PowerShell 5.1)** : branche « déjà à jour » et
branche « MAJ requise » (DryRun, 0 install), détection = 1.0.2.
- docs/PROCEDURE_DEPLOIEMENT_LEA_JULIEN.md : procédure (poste neuf / MAJ manuelle / GPO / rollback).
- EXE binaire jamais versionné (deploy/installer/releases/.gitignore).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
181
deploy/gpo/Deploy-LeaUpdate.ps1
Normal file
181
deploy/gpo/Deploy-LeaUpdate.ps1
Normal file
@@ -0,0 +1,181 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Met a jour l'agent Lea (installe per-user) via un script d'OUVERTURE DE SESSION GPO.
|
||||
|
||||
.DESCRIPTION
|
||||
============================================================================
|
||||
A DEPLOYER EN : User Configuration > Policies > Windows Settings >
|
||||
Scripts (Logon/Logoff) > Logon.
|
||||
ET PAS EN "Computer > Startup".
|
||||
============================================================================
|
||||
RAISON (non negociable) : l'installeur Lea est PER-USER
|
||||
(%LOCALAPPDATA%\Programs\Lea, cle de desinstallation sous HKCU). Un script de
|
||||
DEMARRAGE MACHINE tourne en contexte SYSTEM : il ne verrait NI l'installation
|
||||
NI HKCU du collaborateur -> il ne mettrait jamais rien a jour. Le contexte
|
||||
UTILISATEUR est donc obligatoire.
|
||||
|
||||
Le script, a chaque ouverture de session :
|
||||
1. Detecte la version installee (DisplayVersion de la cle de desinstallation
|
||||
Inno dans HKCU — primaire pour un install EXE ; fallback RPA_AGENT_VERSION
|
||||
du config.txt, present uniquement sur les installs via ZIP).
|
||||
2. La compare a la version cible (comparaison semver correcte :
|
||||
1.0.2 < 1.0.10, contrairement a une comparaison de chaines).
|
||||
3. Si plus ancienne : lance l'installeur en mode SILENCIEUX + UPGRADE-SAFE
|
||||
(SANS /CONFIG -> machine_id, serveur et token du poste PRESERVES).
|
||||
4. Journalise le resultat. IDEMPOTENT : ne refait rien si deja a jour.
|
||||
|
||||
Ne leve JAMAIS d'exception bloquant l'ouverture de session (tout en try/catch,
|
||||
sortie 0 sur erreur non geree).
|
||||
|
||||
.NOTES
|
||||
Execution : configurer la GPO pour lancer
|
||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File Deploy-LeaUpdate.ps1
|
||||
|
||||
Test sur un poste (lecture seule, ne telecharge/installe RIEN) :
|
||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File Deploy-LeaUpdate.ps1 -DryRun
|
||||
#>
|
||||
|
||||
param(
|
||||
# -DryRun : teste la DECISION (version installee vs cible) et journalise ce
|
||||
# qui SERAIT fait, sans rien telecharger ni installer. Pour valider un poste.
|
||||
[switch]$DryRun,
|
||||
# Overrides optionnels (sinon = valeurs du bloc PARAMETRES ci-dessous).
|
||||
# Utiles pour tester un poste (cible bumpee, journal local) sans editer le script.
|
||||
[string]$TargetVersionOverride,
|
||||
[string]$LogShareOverride
|
||||
)
|
||||
|
||||
# ============================================================================
|
||||
# PARAMETRES A ADAPTER PAR LE DSI / Julien (les 3 seules lignes a toucher)
|
||||
# ============================================================================
|
||||
|
||||
# Source de l'installeur : chemin UNC du domaine (recommande) OU URL http(s).
|
||||
# UNC : \\SRV-FICHIERS\Deploiement$\Lea\Lea-Setup-v1.0.2.exe
|
||||
# HTTPS : https://lea.labs.laurinebazin.design/api/fleet/installer/exe
|
||||
$ExeSource = '\\SRV-FICHIERS\Deploiement$\Lea\Lea-Setup-v1.0.2.exe'
|
||||
|
||||
# Version cible : DOIT correspondre a l'EXE ci-dessus.
|
||||
$TargetVersion = '1.0.2'
|
||||
|
||||
# Dossier de journalisation partage (audit Julien). Vide => journal local %TEMP%.
|
||||
$LogShare = '\\SRV-FICHIERS\Deploiement$\Lea\logs'
|
||||
|
||||
# ============================================================================
|
||||
# Ne rien modifier en dessous de cette ligne.
|
||||
# ============================================================================
|
||||
|
||||
# Overrides de ligne de commande (prioritaires sur le bloc PARAMETRES).
|
||||
if ($TargetVersionOverride) { $TargetVersion = $TargetVersionOverride }
|
||||
if ($PSBoundParameters.ContainsKey('LogShareOverride')) { $LogShare = $LogShareOverride }
|
||||
|
||||
$InstallDir = Join-Path $env:LOCALAPPDATA 'Programs\Lea'
|
||||
$ConfigTxt = Join-Path $InstallDir 'config.txt'
|
||||
$AppUninst = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\{B3F9A1E2-5C4D-4E7F-9A1B-2C3D4E5F6789}_is1'
|
||||
|
||||
function Write-Log([string]$msg) {
|
||||
$line = '{0} {1}\{2} {3}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $env:COMPUTERNAME, $env:USERNAME, $msg
|
||||
Write-Output $line
|
||||
# Journalisation best-effort : ne DOIT jamais perturber l'ouverture de session.
|
||||
# -ErrorAction SilentlyContinue car un partage injoignable produit une erreur
|
||||
# NON-terminante (non capturee par try/catch) — verifie sur poste reel .11.
|
||||
try {
|
||||
$dir = if ($LogShare) { $LogShare } else { Join-Path $env:TEMP 'Lea-update-logs' }
|
||||
if (-not (Test-Path $dir -ErrorAction SilentlyContinue)) {
|
||||
New-Item -ItemType Directory -Path $dir -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
}
|
||||
$file = Join-Path $dir ('{0}_{1}.log' -f $env:COMPUTERNAME, $env:USERNAME)
|
||||
Add-Content -Path $file -Value $line -Encoding UTF8 -ErrorAction SilentlyContinue
|
||||
} catch { }
|
||||
}
|
||||
|
||||
function Get-InstalledVersion {
|
||||
# 1. Source de verite pour un install EXE (Inno) : DisplayVersion dans HKCU
|
||||
# (install per-user). Toujours ecrite par l'installeur -> methode primaire.
|
||||
# Verifie sur poste reel .11 : le config.txt genere par l'EXE ne contient
|
||||
# PAS de ligne de version, seul le registre fait foi.
|
||||
if (Test-Path $AppUninst) {
|
||||
$dv = (Get-ItemProperty -Path $AppUninst -Name DisplayVersion -ErrorAction SilentlyContinue).DisplayVersion
|
||||
if ($dv) { return $dv }
|
||||
}
|
||||
# 2. Fallback : RPA_AGENT_VERSION dans config.txt (present sur les installs
|
||||
# via ZIP/Python ; absent des installs via EXE).
|
||||
if (Test-Path $ConfigTxt) {
|
||||
$m = Select-String -Path $ConfigTxt -Pattern '^\s*RPA_AGENT_VERSION\s*=\s*(.+?)\s*$' -ErrorAction SilentlyContinue
|
||||
if ($m) { return $m.Matches[0].Groups[1].Value.Trim() }
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
function ConvertTo-VersionParts([string]$v) {
|
||||
$clean = ($v -replace '^[vV]', '').Trim()
|
||||
$parts = New-Object System.Collections.Generic.List[int]
|
||||
foreach ($p in ($clean -split '\.')) {
|
||||
$n = 0
|
||||
if ([int]::TryParse($p, [ref]$n)) { $parts.Add($n) } else { $parts.Add(0) }
|
||||
}
|
||||
while ($parts.Count -lt 3) { $parts.Add(0) }
|
||||
return $parts
|
||||
}
|
||||
|
||||
function Compare-Semver([string]$a, [string]$b) {
|
||||
# -1 si a<b, 0 si egal, 1 si a>b. Tolerant (piege 1.0.2 < 1.0.10).
|
||||
$pa = ConvertTo-VersionParts $a
|
||||
$pb = ConvertTo-VersionParts $b
|
||||
$max = [Math]::Max($pa.Count, $pb.Count)
|
||||
for ($i = 0; $i -lt $max; $i++) {
|
||||
$va = if ($i -lt $pa.Count) { $pa[$i] } else { 0 }
|
||||
$vb = if ($i -lt $pb.Count) { $pb[$i] } else { 0 }
|
||||
if ($va -lt $vb) { return -1 }
|
||||
if ($va -gt $vb) { return 1 }
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
try {
|
||||
$installed = Get-InstalledVersion
|
||||
if (-not $installed) {
|
||||
Write-Log 'Lea non installe sur ce profil -> ignore (les nouveaux postes passent par le dashboard).'
|
||||
exit 0
|
||||
}
|
||||
if ((Compare-Semver $installed $TargetVersion) -ge 0) {
|
||||
Write-Log ('Deja a jour (installe={0}, cible={1}) -> rien a faire.' -f $installed, $TargetVersion)
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Log ('[DryRun] MAJ qui SERAIT appliquee : {0} -> {1}. Aucune action (ni telechargement ni installation).' -f $installed, $TargetVersion)
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Log ('MAJ requise : installe={0} < cible={1}. Recuperation de l''installeur...' -f $installed, $TargetVersion)
|
||||
|
||||
# Recuperer l'EXE (UNC ou URL) vers un fichier temporaire local.
|
||||
$localExe = Join-Path $env:TEMP ('Lea-Setup-{0}.exe' -f $TargetVersion)
|
||||
if ($ExeSource -match '^(?i)https?://') {
|
||||
Invoke-WebRequest -Uri $ExeSource -OutFile $localExe -UseBasicParsing
|
||||
} else {
|
||||
Copy-Item -Path $ExeSource -Destination $localExe -Force
|
||||
}
|
||||
if (-not (Test-Path $localExe)) {
|
||||
Write-Log ('ECHEC : installeur introuvable apres recuperation ({0}).' -f $ExeSource)
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Installation SILENCIEUSE + UPGRADE-SAFE (sans /CONFIG : identite du poste preservee).
|
||||
# L'installeur arrete Lea (via lock), sauvegarde <app>_backup, puis met a jour.
|
||||
$logInstall = Join-Path $env:TEMP ('Lea-upgrade-{0}.log' -f (Get-Date -Format 'yyyyMMdd_HHmmss'))
|
||||
$installArgs = @('/VERYSILENT', '/SUPPRESSMSGBOXES', '/NORESTART', ('/LOG={0}' -f $logInstall))
|
||||
$proc = Start-Process -FilePath $localExe -ArgumentList $installArgs -Wait -PassThru
|
||||
$rc = $proc.ExitCode
|
||||
|
||||
if ($rc -eq 0) {
|
||||
$now = Get-InstalledVersion
|
||||
Write-Log ('MAJ OK : {0} -> {1} (code 0).' -f $installed, $now)
|
||||
} else {
|
||||
Write-Log ('ECHEC MAJ : code {0}. Journal installeur : {1}.' -f $rc, $logInstall)
|
||||
}
|
||||
exit $rc
|
||||
} catch {
|
||||
Write-Log ('ERREUR non geree : ' + $_.Exception.Message)
|
||||
exit 0 # ne JAMAIS bloquer l'ouverture de session
|
||||
}
|
||||
5
deploy/installer/releases/.gitignore
vendored
Normal file
5
deploy/installer/releases/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# L'installeur EXE (~33 Mo binaire) est déposé ici mais JAMAIS versionné.
|
||||
# On garde le dossier + son LISEZMOI, on ignore tout le reste.
|
||||
*
|
||||
!.gitignore
|
||||
!LISEZMOI.txt
|
||||
17
deploy/installer/releases/LISEZMOI.txt
Normal file
17
deploy/installer/releases/LISEZMOI.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
============================================================
|
||||
deploy/installer/releases/ — Depot des installeurs EXE
|
||||
============================================================
|
||||
|
||||
DEPOSER ICI l'installeur "Lea-Setup-vX.Y.Z.exe" (buildé sur .11).
|
||||
|
||||
Le dashboard sert le plus RECENT via la route :
|
||||
GET /api/fleet/installer
|
||||
-> paquet ZIP "Lea-Install-Silencieux-vX.Y.Z.zip"
|
||||
(EXE + install_silencieux.bat + enroll.txt pré-rempli + LISEZMOI)
|
||||
|
||||
L'EXE (~33 Mo binaire) n'est VOLONTAIREMENT pas versionné dans git.
|
||||
Pour pointer ailleurs : variable d'environnement RPA_LEA_RELEASES_DIR.
|
||||
|
||||
Ce fichier LISEZMOI.txt sert uniquement à garder le dossier présent
|
||||
dans le dépôt (l'EXE, lui, est déposé à la main / par script de release).
|
||||
============================================================
|
||||
40
deploy/installer/silent/LISEZMOI_SILENCIEUX.txt
Normal file
40
deploy/installer/silent/LISEZMOI_SILENCIEUX.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
============================================================
|
||||
Lea - Installation silencieuse (nouveau poste)
|
||||
============================================================
|
||||
|
||||
CE DOSSIER CONTIENT :
|
||||
- Lea-Setup-vX.Y.Z.exe : l'installeur Lea
|
||||
- install_silencieux.bat : le lanceur d'installation
|
||||
- enroll.txt : les parametres d'enrolement a remplir
|
||||
- LISEZMOI_SILENCIEUX.txt : ce fichier
|
||||
|
||||
------------------------------------------------------------
|
||||
QUAND UTILISER CETTE VOIE ?
|
||||
------------------------------------------------------------
|
||||
Pour installer Lea sur un poste qui NE l'a PAS encore.
|
||||
(Pour METTRE A JOUR un poste deja installe : voir la voie GPO,
|
||||
ou relancer simplement l'installeur qui detecte l'existant.)
|
||||
|
||||
------------------------------------------------------------
|
||||
PROCEDURE (3 etapes, ~2 min, sans droits administrateur)
|
||||
------------------------------------------------------------
|
||||
1. Ouvrir "enroll.txt" avec le Bloc-notes.
|
||||
Renseigner : USER_NAME, USER_EMAIL, SERVER_URL, API_TOKEN.
|
||||
(Remplacer les valeurs "CONFIGURE_ME".) Enregistrer.
|
||||
|
||||
2. Double-cliquer sur "install_silencieux.bat".
|
||||
L'installation se deroule sans fenetre d'installation.
|
||||
Ne pas fermer la fenetre noire avant le message "OK".
|
||||
|
||||
3. Verifier que Lea demarre (icone dans la barre des taches,
|
||||
pres de l'horloge). C'est termine.
|
||||
|
||||
------------------------------------------------------------
|
||||
EN CAS DE PROBLEME
|
||||
------------------------------------------------------------
|
||||
- Message "valeurs CONFIGURE_ME" : enroll.txt n'est pas rempli.
|
||||
- Message "aucun Lea-Setup trouve" : l'EXE n'est pas dans ce dossier.
|
||||
- Autre erreur : le journal detaille est indique a l'ecran
|
||||
(dossier %TEMP%, fichier Lea-install-silencieux.log).
|
||||
Le transmettre a l'administrateur AIVANOV.
|
||||
============================================================
|
||||
31
deploy/installer/silent/enroll.txt
Normal file
31
deploy/installer/silent/enroll.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
# ============================================================
|
||||
# enroll.txt — Enrolement pour installation SILENCIEUSE
|
||||
# ------------------------------------------------------------
|
||||
# Utilise par install_silencieux.bat :
|
||||
# Lea-Setup-vX.Y.Z.exe /VERYSILENT /CONFIG=enroll.txt
|
||||
#
|
||||
# L'installeur lit ce fichier au demarrage et remplit les
|
||||
# informations d'enrolement SANS interface graphique.
|
||||
#
|
||||
# A FAIRE : renseigner les valeurs ci-dessous (remplacer les
|
||||
# CONFIGURE_ME), enregistrer, puis lancer install_silencieux.bat.
|
||||
#
|
||||
# Format : CLE=valeur, une ligne par parametre, # = commentaire.
|
||||
# NOTE : ce fichier sert l'INSTALL NEUVE. Sur une mise a jour,
|
||||
# l'installeur preserve tout seul l'identite du poste et
|
||||
# IGNORE ce fichier (voir la voie GPO).
|
||||
# ============================================================
|
||||
|
||||
# --- Identite du collaborateur ---
|
||||
USER_NAME=Prenom Nom
|
||||
USER_EMAIL=prenom.nom@clinique-wallerstein.fr
|
||||
USER_ID=
|
||||
|
||||
# --- Connexion au serveur Lea ---
|
||||
# Exemples de SERVER_URL :
|
||||
# LAN clinique (DGX) : http://192.168.1.178:5005/api/v1
|
||||
# Internet : https://lea.labs.laurinebazin.design/api/v1
|
||||
SERVER_URL=CONFIGURE_ME
|
||||
|
||||
# Token d'authentification (fourni par l'administrateur AIVANOV)
|
||||
API_TOKEN=CONFIGURE_ME
|
||||
73
deploy/installer/silent/install_silencieux.bat
Normal file
73
deploy/installer/silent/install_silencieux.bat
Normal file
@@ -0,0 +1,73 @@
|
||||
@echo off
|
||||
chcp 65001 >nul 2>&1
|
||||
setlocal enabledelayedexpansion
|
||||
title Lea - Installation silencieuse (nouveau poste)
|
||||
|
||||
:: ============================================================
|
||||
:: install_silencieux.bat
|
||||
:: Installe Lea sur un NOUVEAU poste, sans interface graphique.
|
||||
::
|
||||
:: Pre-requis : ce script, l'installeur "Lea-Setup-v*.exe" et
|
||||
:: "enroll.txt" (rempli) doivent etre dans le MEME dossier.
|
||||
::
|
||||
:: Installation PER-USER : aucun droit administrateur requis.
|
||||
:: ============================================================
|
||||
|
||||
set "HERE=%~dp0"
|
||||
set "ENROLL=%HERE%enroll.txt"
|
||||
set "LOG=%TEMP%\Lea-install-silencieux.log"
|
||||
|
||||
echo.
|
||||
echo ============================================================
|
||||
echo Lea - Installation silencieuse (nouveau poste)
|
||||
echo ============================================================
|
||||
echo.
|
||||
|
||||
:: --- 1. Localiser l'installeur (Lea-Setup-v*.exe, version la plus recente) ---
|
||||
set "EXE="
|
||||
for /f "delims=" %%f in ('dir /b /o-n "%HERE%Lea-Setup-v*.exe" 2^>nul') do (
|
||||
if not defined EXE set "EXE=%HERE%%%f"
|
||||
)
|
||||
if not defined EXE (
|
||||
echo ERREUR : aucun "Lea-Setup-v*.exe" trouve dans ce dossier.
|
||||
echo Placez ce script a cote de l'installeur Lea.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo Installeur detecte : !EXE!
|
||||
|
||||
:: --- 2. Verifier enroll.txt ---
|
||||
if not exist "%ENROLL%" (
|
||||
echo ERREUR : "enroll.txt" introuvable a cote de ce script.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
findstr /C:"CONFIGURE_ME" "%ENROLL%" >nul 2>&1
|
||||
if not errorlevel 1 (
|
||||
echo.
|
||||
echo ATTENTION : "enroll.txt" contient encore des valeurs CONFIGURE_ME.
|
||||
echo Ouvrez enroll.txt, renseignez SERVER_URL / API_TOKEN / USER_*,
|
||||
echo enregistrez, puis relancez ce script.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: --- 3. Installation silencieuse (per-user, pas d'admin) ---
|
||||
echo Installation en cours (silencieuse, ~1-2 min)... ne fermez pas cette fenetre.
|
||||
"!EXE!" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /CONFIG="%ENROLL%" /LOG="%LOG%"
|
||||
set "RC=!errorlevel!"
|
||||
|
||||
echo.
|
||||
if "!RC!"=="0" (
|
||||
echo Installation terminee - OK.
|
||||
echo Lea est enrolle et pret. Journal : %LOG%
|
||||
) else (
|
||||
echo ERREUR : l'installation a echoue ^(code !RC!^).
|
||||
echo Consultez le journal : %LOG%
|
||||
)
|
||||
echo.
|
||||
pause
|
||||
endlocal
|
||||
Reference in New Issue
Block a user