# ============================================================ # Omika - Installation du service Windows OmikaDiagnosticsWeb (deploiement 4/6) # ============================================================ # CIBLE : Windows Server 2025 (SRV-OMIKA), PowerShell ADMINISTRATEUR. # NE PAS executer depuis le poste de developpement. # # CE QUE CE SCRIPT FAIT : # 1. Cree le dossier de journalisation. # 2. Pose les ACL NTFS minimales (avec CONTROLE du code retour d'icacls). # 3. CONTROLE qu'aucun appsettings.Development.json n'est present dans la # publication (default-deny : un fichier de dev ferait tomber les # protections Production). # 4. Valide le compte de service (existence + droit de connexion). # 5. Cree le service Windows OmikaDiagnosticsWeb (idempotent, Manual). # 6. Verifie ce qui a ete reellement cree. # # CE QU'IL NE FAIT PAS : # - AUCUN demarrage de service, AUCUN secret ecrit, AUCUNE migration SQL. # - AUCUN certificat TLS (pose sur le reverse proxy Apache). # # PREREQUIS MANUELS : # - Compte local dedie + droit « Ouvrir une session en tant que service ». # - Publication copiee dans \Apps\DiagnosticsWeb. # - PostgreSQL joignable + migrations 001 -> 010 appliquees. # - Premier Admin : voir DEPLOIEMENT_PRODUCTION_DIAGNOSTICS.md §22 (12 etapes). # # IDEMPOTENT - prend en charge -WhatIf. # # EXEMPLES : # .\Install-OmikaDiagnosticsWeb.ps1 # .\Install-OmikaDiagnosticsWeb.ps1 -WhatIf # .\Install-OmikaDiagnosticsWeb.ps1 -Desinstaller # ============================================================ [CmdletBinding(SupportsShouldProcess = $true)] param( [string]$InstallRoot = 'C:\Omika', [string]$ServiceName = 'OmikaDiagnosticsWeb', [string]$Account = '.\svc_omika_diagweb', [ValidateSet('Manual', 'Automatic', 'Disabled')] [string]$StartupType = 'Manual', [switch]$Desinstaller ) $ErrorActionPreference = 'Stop' Import-Module (Join-Path $PSScriptRoot 'Omika.Deploy.Common.psm1') -Force # Le module a son propre etat de session : $WhatIfPreference ne s'y propage pas. $Simulation = [bool]$WhatIfPreference # --- Definition du service --------------------------------------------------- $NomAffiche = 'Omika Diagnostics Web' $DossierApps = 'DiagnosticsWeb' $Executable = 'Omika.Diagnostics.Web.exe' $Description = 'Omika - Interface web de consultation des diagnostics (Kestrel derriere reverse proxy Apache, HTTPS).' $DossiersModifier = @( 'Logs\DiagnosticsWeb' ) try { Assert-OmikaAdmin $chemins = Get-OmikaPaths -InstallRoot $InstallRoot $dossierPublie = Join-Path $chemins.Apps $DossierApps $cheminExe = Join-Path $dossierPublie $Executable # --- Rollback ------------------------------------------------------------ if ($Desinstaller) { Write-OmikaStep "Desinstallation du service $ServiceName" Remove-OmikaService -Name $ServiceName -WhatIf:$Simulation | Out-Null Write-OmikaServiceSummary -Name $ServiceName -Supprime exit 0 } # --- 1. Dossiers --------------------------------------------------------- Write-OmikaStep 'Dossiers du service' foreach ($relatif in $DossiersModifier) { New-OmikaDirectory -Path (Join-Path $InstallRoot $relatif) -WhatIf:$Simulation | Out-Null } # --- 2. ACL -------------------------------------------------------------- Write-OmikaStep 'ACL NTFS minimales' foreach ($relatif in $DossiersModifier) { Grant-OmikaAcl -Path (Join-Path $InstallRoot $relatif) -Account $Account -Right 'M' ` -RequireExisting -WhatIf:$Simulation | Out-Null } # --- 3. Controle default-deny ------------------------------------------- Write-OmikaStep 'Controle de la publication (default-deny)' if (Test-Path -LiteralPath $dossierPublie) { $fichiersInterdits = @('appsettings.Development.json', 'appsettings.Test.json') $trouve = $false foreach ($nom in $fichiersInterdits) { $chemin = Join-Path $dossierPublie $nom if (Test-Path -LiteralPath $chemin) { Write-OmikaWarn "Fichier de developpement PRESENT dans la publication : $nom" Write-OmikaWarn ' -> la configuration de developpement peut desactiver les protections Production.' Write-OmikaWarn ' -> supprimez-le de la publication avant de demarrer le service.' $trouve = $true } } if (-not $trouve) { Write-OmikaOk 'Aucun fichier de configuration de developpement dans la publication.' } } else { Write-OmikaWarn "Publication absente : $dossierPublie (deployez les binaires d'abord)." } # --- 4. Compte de service ------------------------------------------------ Write-OmikaStep 'Compte de service' Assert-OmikaServiceAccount -Account $Account | Out-Null # --- 5. Service Windows -------------------------------------------------- Write-OmikaStep "Creation du service Windows ($StartupType)" Install-OmikaService -Name $ServiceName -DisplayName $NomAffiche ` -ExePath $cheminExe -Account $Account -Description $Description ` -StartupType $StartupType -WhatIf:$Simulation | Out-Null # --- 6. Recapitulatif ---------------------------------------------------- Write-OmikaServiceSummary -Name $ServiceName -ExePath $cheminExe -Account $Account -Rappels @( 'Injecter les secrets en variables MACHINE (aucun secret dans ce script) :' ' ConnectionStrings__DiagnosticsDatabase=Host=127.0.0.1;Port=5432;Database=omika_diagnostics;Username=omika_diagnostics_web;Password=' ' ASPNETCORE_ENVIRONMENT=Production (OBLIGATOIRE : default-deny, PAS Development)' ' ASPNETCORE_URLS=http://127.0.0.1:' ' DiagnosticsWeb__PathBase=' 'Premier Admin (DEPLOIEMENT_PRODUCTION_DIAGNOSTICS.md §22) :' ' 1. configurer TEMPORAIREMENT DiagnosticsAuth__Operators__0__Username / __PasswordHash / __Roles__0=Admin' ' 2. demarrer, se connecter, creer l''Admin DB dans /Users' ' 3. RETIRER l''operateur bootstrap (DiagnosticsAuth:Operators = []) puis redemarrer' ' 4. confirmer que le bootstrap est refuse et que l''Admin DB fonctionne' 'Les mots de passe ne sont JAMAIS dans un appsettings versionne (hash uniquement).' 'Exposer en HTTPS via le reverse proxy Apache, jamais Kestrel en direct.' ) exit 0 } catch { Write-OmikaFail $_.Exception.Message exit 1 }