DeployCenter

This commit is contained in:
benoit committed 2026-10-15 21:15:33 +02:00
commit 7c724d475e
14 files changed
+2460

No files matched your search

+1
View File
@@ -0,0 +1 @@
Logs/*
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

+12
View File
@@ -0,0 +1,12 @@
; Preferences DeployCenter
; Le fichier est lu au démarrage et n'est jamais modifié automatiquement.
[General]
Theme=Light
[Sources]
Paths=%DEPLOY_VOLUME%
[UltraVNC]
; Laisser vide pour générer un mot de passe aléatoire à chaque lancement.
; Pour les tests, renseigner un mot de passe ici. Il sera encodé dans ultravnc.ini par createpassword64.exe.
Password=
+1817
View File
File diff suppressed because it is too large. Load diff
+179
View File
@@ -0,0 +1,179 @@
# HardwareInfo.ps1
# DeployCenter - Inventaire matériel
# Compatible Windows PowerShell 5.1 / WinPE
function Get-HardwareInfo {
[CmdletBinding()]
param()
$info = [ordered]@{
Manufacturer = "Inconnu"
Model = "Inconnu"
SerialNumber = "Inconnu"
Firmware = "Inconnu"
Architecture = $env:PROCESSOR_ARCHITECTURE
WinPE = $false
Disks = @()
Errors = @()
}
# Fabricant et modele du PC
try {
$computer = Get-CimInstance `
-ClassName Win32_ComputerSystem `
-ErrorAction Stop
if ($computer.Manufacturer) {
$info.Manufacturer = $computer.Manufacturer.Trim()
}
if ($computer.Model) {
$info.Model = $computer.Model.Trim()
}
}
catch {
$info.Errors += "Modele du PC : $($_.Exception.Message)"
}
# Numero de serie
try {
$bios = Get-CimInstance `
-ClassName Win32_BIOS `
-ErrorAction Stop
if ($bios.SerialNumber) {
$info.SerialNumber = $bios.SerialNumber.Trim()
}
}
catch {
$info.Errors += "Numero de serie : $($_.Exception.Message)"
}
# Detection du firmware
try {
$firmwareKey = Get-ItemProperty `
-Path "HKLM:\SYSTEM\CurrentControlSet\Control" `
-Name PEFirmwareType `
-ErrorAction Stop
switch ([int]$firmwareKey.PEFirmwareType) {
1 { $info.Firmware = "BIOS (Legacy)" }
2 { $info.Firmware = "UEFI" }
default { $info.Firmware = "Indetermine" }
}
}
catch {
$info.Errors += "Mode firmware indisponible"
}
# Detection de WinPE
$info.WinPE = Test-Path `
"HKLM:\SYSTEM\CurrentControlSet\Control\MiniNT"
# Inventaire des disques physiques
try {
$disks = Get-CimInstance `
-ClassName Win32_DiskDrive `
-ErrorAction Stop
foreach ($disk in $disks) {
$info.Disks += [PSCustomObject]@{
Index = [int]$disk.Index
Model = $disk.Model
SizeBytes = [long]$disk.Size
SizeGB = [math]::Round(
([double]$disk.Size / 1GB), 1
)
InterfaceType = $disk.InterfaceType
Status = $disk.Status
}
}
}
catch {
$info.Errors += "Inventaire des disques : $($_.Exception.Message)"
}
# Retourner un objet exploitable par les autres modules
[PSCustomObject]$info
}
# ============================================================
# Execution du test
# ============================================================
$LogDirectory = "X:\DeployLogs"
$JsonPath = Join-Path $LogDirectory "hardware.json"
$TextPath = Join-Path $LogDirectory "hardware.log"
try {
New-Item -ItemType Directory `
-Path $LogDirectory `
-Force `
-ErrorAction Stop | Out-Null
}
catch {
throw "Impossible de creer le repertoire de logs : $($_.Exception.Message)"
}
$result = Get-HardwareInfo
# Export JSON en UTF-8 avec BOM sous Windows PowerShell 5.1
try {
$json = $result | ConvertTo-Json -Depth 5
Set-Content `
-Path $JsonPath `
-Value $json `
-Encoding UTF8 `
-ErrorAction Stop
}
catch {
throw "Impossible d'enregistrer le JSON : $($_.Exception.Message)"
}
# Construire un journal texte sans utiliser Write-Host
$lines = @(
"=== DeployCenter - Inventaire materiel ==="
"Date : $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
"Fabricant : $($result.Manufacturer)"
"Modele : $($result.Model)"
"Numero serie : $($result.SerialNumber)"
"Firmware : $($result.Firmware)"
"Architecture : $($result.Architecture)"
"WinPE : $($result.WinPE)"
""
"=== Disques detectes ==="
)
foreach ($disk in $result.Disks) {
$lines += (
"Disque {0} : {1} - {2} Go - {3} - {4}" -f
$disk.Index,
$disk.Model,
$disk.SizeGB,
$disk.InterfaceType,
$disk.Status
)
}
if ($result.Errors.Count -gt 0) {
$lines += ""
$lines += "=== Erreurs ==="
foreach ($message in $result.Errors) {
$lines += $message
}
}
$utf8 = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllLines(
$TextPath,
[string[]]$lines,
$utf8
)
# Renvoyer l'objet comme sortie principale du script
$result
+59
View File
@@ -0,0 +1,59 @@
# DeployCenter - Gestion des journaux
# Compatible Windows PowerShell 5.1
function Initialize-DeployCenterLogging {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$LogRoot,
[AllowNull()]
[string]$IPv4 = $null
)
$script:LogRoot = $LogRoot
if (-not (Test-Path -LiteralPath $script:LogRoot -PathType Container)) {
New-Item -Path $script:LogRoot -ItemType Directory -Force -ErrorAction Stop | Out-Null
}
# L'adresse IPv4 est fournie par Modules\\Network.psm1.
$script:LogIPv4 = $IPv4
$logIpTag = if ([string]::IsNullOrWhiteSpace($script:LogIPv4)) {
'sans-ip'
} else {
$script:LogIPv4 -replace '[^0-9A-Za-z.-]', '_'
}
$script:LogFile = Join-Path $script:LogRoot (
'DeployCenter_{0}_{1}.log' -f $logIpTag, (Get-Date -Format 'yyyyMMdd_HHmmss')
)
}
function Write-Log {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$Message,
[ValidateSet('INFO', 'SUCCESS', 'WARNING', 'ERROR')]
[string]$Level = 'INFO'
)
$line = '{0} [{1}] {2}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Level, $Message
try {
[System.IO.File]::AppendAllText(
$script:LogFile,
$line + [Environment]::NewLine,
[System.Text.Encoding]::UTF8
)
} catch {
# Le journal graphique reste disponible si le fichier n'est pas accessible.
}
if ($null -ne $script:txtLog -and -not $script:txtLog.IsDisposed) {
$script:txtLog.AppendText($line + [Environment]::NewLine)
$script:txtLog.SelectionStart = $script:txtLog.TextLength
$script:txtLog.ScrollToCaret()
}
}
+29
View File
@@ -0,0 +1,29 @@
# DeployCenter - Détection réseau
# Compatible Windows PowerShell 5.1
function Get-DeployNetworkIPv4 {
[CmdletBinding()]
param()
# Priorité à une interface avec passerelle par défaut ; exclut loopback,
# APIPA et adresses IPv4 non routables couramment inutiles en WinPE.
$candidates = @()
try {
foreach ($cfg in (Get-CimInstance Win32_NetworkAdapterConfiguration -Filter 'IPEnabled=True' -ErrorAction Stop)) {
$hasGateway = @($cfg.DefaultIPGateway | Where-Object { $_ -match '^\d{1,3}(\.\d{1,3}){3}$' }).Count -gt 0
foreach ($address in @($cfg.IPAddress | Where-Object { $_ -match '^\d{1,3}(\.\d{1,3}){3}$' })) {
if ($address -eq '127.0.0.1' -or $address -like '169.254.*' -or $address -eq '0.0.0.0') { continue }
$candidates += [pscustomobject]@{ Address = $address; HasGateway = $hasGateway; Index = [int]$cfg.Index }
}
}
} catch {
# La détection réseau ne doit pas empêcher le démarrage de DeployCenter.
if (Get-Command Write-Log -ErrorAction SilentlyContinue) {
Write-Log "Détection réseau WMI : $($_.Exception.Message)" 'WARNING'
}
}
$chosen = $candidates | Sort-Object @{Expression='HasGateway';Descending=$true}, Index | Select-Object -First 1
if ($chosen) { return [string]$chosen.Address }
return $null
}
+62
View File
@@ -0,0 +1,62 @@
Set-StrictMode -Version 2.0
function ConvertFrom-ThemeColor {
param([Parameter(Mandatory=$true)][string]$Value)
$hex = $Value.Trim().TrimStart('#')
if ($hex -notmatch '^[0-9A-Fa-f]{6}$') {
throw "Couleur invalide dans un thème : '$Value'. Utiliser #RRGGBB."
}
return [System.Drawing.Color]::FromArgb(
[Convert]::ToInt32($hex.Substring(0,2),16),
[Convert]::ToInt32($hex.Substring(2,2),16),
[Convert]::ToInt32($hex.Substring(4,2),16)
)
}
function Get-DeployCenterThemeNames {
param([Parameter(Mandatory=$true)][string]$ThemesRoot)
$names = @()
foreach ($file in (Get-ChildItem -LiteralPath $ThemesRoot -Filter '*.psd1' -File -ErrorAction SilentlyContinue)) {
if ($file.BaseName -match '^[A-Za-z0-9_-]+$') { $names += $file.BaseName }
}
return @($names | Sort-Object -Unique)
}
function Import-DeployCenterTheme {
param(
[Parameter(Mandatory=$true)][string]$ThemesRoot,
[Parameter(Mandatory=$true)][string]$ThemeName
)
if ($ThemeName -notmatch '^[A-Za-z0-9_-]+$') { throw "Nom de thème invalide : $ThemeName" }
$path = Join-Path $ThemesRoot ($ThemeName + '.psd1')
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { throw "Thème introuvable : $ThemeName" }
$data = Import-PowerShellDataFile -LiteralPath $path
$required = @('Background','Panel','PanelAlt','Text','Secondary','Accent','Success','Border','Danger')
foreach ($key in $required) {
if (-not $data.ContainsKey($key)) { throw "Le thème '$ThemeName' ne contient pas la clé '$key'." }
}
$theme = @{}
foreach ($key in $required) { $theme[$key] = ConvertFrom-ThemeColor -Value ([string]$data[$key]) }
foreach ($key in @('TableHeader','TableRowEven','TableRowOdd')) {
if ($data.ContainsKey($key)) { $theme[$key] = ConvertFrom-ThemeColor -Value ([string]$data[$key]) }
else { $theme[$key] = $theme.PanelAlt }
}
$buttonDefaults = @{
Button = @{ Background=$theme.PanelAlt; Foreground=$theme.Text; Border=$theme.Border; HoverBackground=$theme.Panel; PressedBackground=$theme.Border; DisabledBackground=$theme.Panel; DisabledForeground=$theme.Secondary }
PrimaryButton = @{ Background=$theme.Accent; Foreground=[System.Drawing.Color]::White; Border=$theme.Accent; HoverBackground=$theme.Accent; PressedBackground=$theme.Accent; DisabledBackground=$theme.PanelAlt; DisabledForeground=$theme.Secondary }
DangerButton = @{ Background=$theme.Danger; Foreground=[System.Drawing.Color]::White; Border=$theme.Danger; HoverBackground=$theme.Danger; PressedBackground=$theme.Danger; DisabledBackground=$theme.PanelAlt; DisabledForeground=$theme.Secondary }
}
foreach ($role in @('Button','PrimaryButton','DangerButton')) {
$theme[$role] = @{}
$provided = $data[$role]
foreach ($property in @('Background','Foreground','Border','HoverBackground','PressedBackground','DisabledBackground','DisabledForeground')) {
$raw = $null
if ($provided -is [System.Collections.IDictionary] -and $provided.Contains($property)) { $raw = [string]$provided[$property] }
if ([string]::IsNullOrWhiteSpace($raw)) { $theme[$role][$property] = $buttonDefaults[$role][$property] }
else { $theme[$role][$property] = ConvertFrom-ThemeColor -Value $raw }
}
}
return $theme
}
Export-ModuleMember -Function ConvertFrom-ThemeColor, Get-DeployCenterThemeNames, Import-DeployCenterTheme
+22
View File
@@ -0,0 +1,22 @@
function Set-DeployCenterButtonStyle {
param(
[Parameter(Mandatory=$true)][System.Windows.Forms.Button]$Button,
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
[ValidateSet('Button','PrimaryButton','DangerButton')][string]$Role = 'Button'
)
$style = $Theme[$Role]
$Button.BackColor = $style.Background
$Button.ForeColor = $style.Foreground
$Button.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$Button.UseVisualStyleBackColor = $false
$Button.FlatAppearance.BorderSize = 1
$Button.FlatAppearance.BorderColor = $style.Border
$Button.FlatAppearance.MouseOverBackColor = $style.HoverBackground
$Button.FlatAppearance.MouseDownBackColor = $style.PressedBackground
if (-not $Button.Enabled) {
$Button.BackColor = $style.DisabledBackground
$Button.ForeColor = $style.DisabledForeground
}
}
Export-ModuleMember -Function Set-DeployCenterButtonStyle
+127
View File
@@ -0,0 +1,127 @@
# Module VNC de DeployCenter
# Exécuté uniquement avec -Vnc dans le scope principal pour partager le contexte WinPE.
function Start-DeployCenterVnc {
$parentRoot = Split-Path -Path $script:DeployRoot -Parent
$sourceVnc = Join-Path $parentRoot 'uvnc'
$sourceExe = Join-Path $sourceVnc 'winvnc.exe'
$passwordTool = Join-Path $sourceVnc 'createpassword64.exe'
$sourceIni = Join-Path $sourceVnc 'ultravnc.ini'
$script:DeployIPv4 = Get-DeployNetworkIPv4
if ([string]::IsNullOrWhiteSpace($script:DeployIPv4)) {
Write-Log 'Aucune adresse IPv4 de déploiement détectée.' 'WARNING'
}
if (-not (Test-Path -LiteralPath $sourceExe -PathType Leaf)) {
Write-Log "UltraVNC non démarré : exécutable absent ($sourceExe)." 'WARNING'
Write-DeployInventory
return
}
if (-not (Test-Path -LiteralPath $passwordTool -PathType Leaf)) {
Write-Log "UltraVNC non démarré : createpassword64.exe absent ($passwordTool)." 'WARNING'
Write-DeployInventory
return
}
if (-not (Test-Path -LiteralPath $sourceIni -PathType Leaf)) {
Write-Log "UltraVNC non démarré : fichier absent ($sourceIni)." 'WARNING'
Write-DeployInventory
return
}
try {
if (Test-Path -LiteralPath $script:VncDirectory) {
Remove-Item -LiteralPath $script:VncDirectory -Recurse -Force -ErrorAction Stop
}
New-Item -Path $script:VncDirectory -ItemType Directory -Force | Out-Null
Copy-Item -Path (Join-Path $sourceVnc '*') -Destination $script:VncDirectory -Recurse -Force
# WinPE ne permet pas toujours d'ajouter des règles de pare-feu.
# La désactivation globale n'est effectuée que lorsque VNC est demandé.
$wpeutil = Join-Path $env:WINDIR 'System32\wpeutil.exe'
if (-not (Test-Path -LiteralPath $wpeutil -PathType Leaf)) {
$wpeutil = 'wpeutil.exe'
}
& $wpeutil DisableFirewall
if ($LASTEXITCODE -ne 0) {
throw "wpeutil DisableFirewall a renvoyé le code $LASTEXITCODE."
}
Write-Log 'Pare-feu WinPE désactivé à la demande de -Vnc.' 'WARNING'
# Force le mode portable : l'INI actif est celui placé à côté de winvnc.exe.
$portableFlag = Join-Path $script:VncDirectory 'ultravnc.portable'
Set-Content -LiteralPath $portableFlag -Value '' -Encoding ASCII
if (-not [string]::IsNullOrWhiteSpace([string]$script:Config.VncPassword)) {
$script:VncPassword = [string]$script:Config.VncPassword
$passwordSource = 'configuré dans DeployCenter.ini'
}
else {
$script:VncPassword = -join (1..8 | ForEach-Object {
$alphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789'
$alphabet[(Get-Random -Minimum 0 -Maximum $alphabet.Length)]
})
$passwordSource = 'généré automatiquement'
}
# createpassword64 encode le mot de passe choisi dans le champ passwd d'ultravnc.ini.
$tool = Join-Path $script:VncDirectory 'createpassword64.exe'
$script:VncProcess = Start-Process -FilePath $tool -ArgumentList @($script:VncPassword) `
-WorkingDirectory $script:VncDirectory -Wait -PassThru -WindowStyle Hidden
if ($script:VncProcess.ExitCode -ne 0) {
throw "createpassword64.exe a renvoyé le code $($script:VncProcess.ExitCode)."
}
$activeIni = Join-Path $script:VncDirectory 'ultravnc.ini'
if (-not (Test-Path -LiteralPath $activeIni -PathType Leaf) -or
-not (Select-String -LiteralPath $activeIni -Pattern '^passwd\s*=' -Quiet)) {
throw "createpassword64.exe n'a pas créé le champ passwd dans ultravnc.ini."
}
$server = Join-Path $script:VncDirectory 'winvnc.exe'
$script:VncProcess = Start-Process -FilePath $server -ArgumentList @('-run') `
-WorkingDirectory $script:VncDirectory -PassThru -WindowStyle Hidden
Start-Sleep -Milliseconds 800
if ($script:VncProcess.HasExited) {
throw "winvnc.exe s'est arrêté immédiatement (code $($script:VncProcess.ExitCode))."
}
$script:VncStarted = $true
Write-Log "UltraVNC démarré. IP : $($script:DeployIPv4) ; mot de passe $passwordSource." 'SUCCESS'
} catch {
Write-Log "Échec du démarrage UltraVNC : $($_.Exception.Message)" 'ERROR'
$script:VncStarted = $false
$script:VncPassword = $null
}
Write-DeployInventory
}
function Stop-DeployCenterVnc {
try {
if ($null -ne $script:VncProcess) {
$proc = Get-Process -Id $script:VncProcess.Id -ErrorAction SilentlyContinue
if ($null -ne $proc) { Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue }
}
# Au cas où winvnc lance un processus serveur distinct, ne cibler que les
# processus dont le chemin correspond à notre copie temporaire.
foreach ($proc in (Get-CimInstance Win32_Process -Filter "Name='winvnc.exe'" -ErrorAction SilentlyContinue)) {
if ($proc.ExecutablePath -and $proc.ExecutablePath.StartsWith($script:VncDirectory, [StringComparison]::OrdinalIgnoreCase)) {
Stop-Process -Id $proc.ProcessId -Force -ErrorAction SilentlyContinue
}
}
} catch {
Write-Log "Arrêt UltraVNC : $($_.Exception.Message)" 'WARNING'
}
# Le processus winvnc peut conserver brièvement un handle sur son dossier.
# Le dossier VNC est propre à ce processus PowerShell (uvnc_<PID>) : on ne
# supprime pas récursivement le dossier partagé InventoryDir, ce qui évite
# de bloquer le lancement suivant si un handle est encore ouvert.
try {
if (Test-Path -LiteralPath $script:InventoryFile -PathType Leaf) {
Remove-Item -LiteralPath $script:InventoryFile -Force -ErrorAction SilentlyContinue
}
if (Test-Path -LiteralPath $script:VncDirectory -PathType Container) {
Start-Sleep -Milliseconds 500
Remove-Item -LiteralPath $script:VncDirectory -Recurse -Force -ErrorAction SilentlyContinue
}
} catch { }
}
+94
View File
@@ -0,0 +1,94 @@
# DeployCenter — première version de la réécriture
## Contenu
- `DeployCenter.ps1` : point d'entrée et logique applicative existante.
- `Modules/ThemeManager.psm1` : découverte, chargement et validation des thèmes PSD1, avec prise en charge des rôles de boutons.
- `Modules/UI.psm1` : style centralisé des boutons (normal, survol, appui et désactivé).
- `Themes/Light.psd1` et `Themes/Dark.psd1` : palettes et styles des boutons.
## Lancement
Depuis le dossier DeployCenter, lancer :
```powershell
powershell.exe -ExecutionPolicy Bypass -File .\DeployCenter.ps1
```
Pour lancer en fenêtre redimensionnable :
```powershell
powershell.exe -ExecutionPolicy Bypass -File .\DeployCenter.ps1 -Windowed
```
Conserver à côté du script les ressources habituelles du projet (`Assets`, `uvnc`, `HardwareInfo.ps1`, etc.). Les dossiers `Modules` et `Themes` doivent rester à côté de `DeployCenter.ps1`.
## Mise en page
Le redimensionnement de la fenêtre recalcule désormais les largeurs des panneaux, la taille du tableau et du journal, ainsi que la position des boutons. Les marges et hauteurs des contrôles restent volontairement fixes pour préserver la lisibilité sous WinPE.
## Limites connues de cette première étape
Cette version centralise le chargement des thèmes et le style des boutons, et introduit une mise en page adaptative. La logique de déploiement, la détection des sources, l'inventaire et UltraVNC restent pour l'instant dans le script principal : leur extraction en modules indépendants doit être faite progressivement afin de ne pas casser les dépendances PowerShell ni le fonctionnement WinPE.
Le script n'a pas pu être exécuté dans cet environnement, faute de moteur Windows PowerShell/WinForms. Il doit être validé sur la machine WinPE cible avant remplacement de la version actuelle.
## Mot de passe UltraVNC de test
Dans `DeployCenter.ini`, ajoutez la section suivante. Un champ `Password` non vide est utilisé tel quel au lieu de générer un mot de passe aléatoire ; `createpassword64.exe` continue à le convertir dans le format attendu par UltraVNC. Laissez `Password=` vide pour conserver le comportement par défaut.
```ini
[UltraVNC]
Password=MonMotDePasseDeTest
```
Le mot de passe est stocké en clair dans `DeployCenter.ini` : utilisez cette option uniquement dans un environnement de test protégé.
### Correctifs v3
- En-têtes du tableau des éditions Windows avec une couleur dédiée définie par le thème (`TableHeader`).
- Sélection unique explicite dans la liste des éditions et dessin de la sélection basé sur l'élément réellement sélectionné.
### Correctif v12 — pied de page
- La fenêtre principale affiche l'adresse IP de déploiement et le mot de passe UltraVNC dans son pied de page.
- Le pied de page commun reste activé par défaut ; le paramètre `-ShowFooter $false` permet de le masquer dans la fenêtre « Éditions Windows ». Les autres fenêtres conservent leur comportement habituel.
### Correctif v15 — pied de page cohérent
- Le pied de page commun affiche par défaut l’adresse IP et le mot de passe VNC dans toutes les fenêtres qui l’utilisent.
- Seule la fenêtre de sélection « Éditions Windows » masque entièrement le pied de page via `-ShowFooter $false`.
### Alternance des lignes des tableaux
Les tableaux utilisent une alternance paire/impaire définie dans chaque thème (`TableRowEven` et `TableRowOdd`). La sélection conserve la couleur d’accent du thème. Les valeurs sont partagées par les fenêtres Sources Windows et Éditions Windows.
## Paramètre de démarrage VNC (v18)
- Sans paramètre : UltraVNC ne démarre pas.
- Avec `-vnc` : UltraVNC démarre.
Exemple : `powershell.exe -ExecutionPolicy Bypass -File .\DeployCenter.ps1 -vnc`
## Options de lancement
- Sans paramètre : UltraVNC n'est pas démarré.
- Avec `-Vnc` (alias PowerShell utilisable sous la forme `-vnc`) : UltraVNC est démarré.
- Les fenêtres sont non redimensionnables par défaut via `Set-DeployCenterFormSizing`; passer `-Resizable` à cette fonction commune pour autoriser le redimensionnement.
## Module VNC
La gestion d'UltraVNC est isolée dans `Modules/VNC.psm1`. Le fichier est chargé par dot-sourcing uniquement lorsque `-Vnc` est fourni, afin de conserver le contexte partagé de DeployCenter.
- Sans `-Vnc`, UltraVNC ne démarre pas et DeployCenter ne demande pas la désactivation du pare-feu.
- Avec `-Vnc`, le module VNC exécute `wpeutil DisableFirewall` avant de lancer UltraVNC. Cette commande désactive le pare-feu WinPE dans son ensemble ; utilisez cette option sur un réseau de déploiement maîtrisé.
- Le démarrage VNC et les erreurs sont consignés dans le journal DeployCenter.
## Modules
- `Modules/Network.psm1` : détection de l’adresse IPv4 de déploiement, utilisée par le pied de page et le nom du journal.
- `Modules/Logging.psm1` : initialisation et écriture des journaux. L’adresse IPv4 détectée lui est transmise par le script principal.
+29
View File
@@ -0,0 +1,29 @@
@{
Background = '#171A21'
Panel = '#222731'
PanelAlt = '#1C2029'
TableHeader = '#303744'
TableRowEven = '#303640'
TableRowOdd = '#414956'
Text = '#F1F5F9'
Secondary = '#9CA9BC'
Accent = '#3B82F6'
Success = '#4ADE80'
Border = '#414A59'
Danger = '#EF4444'
Button = @{
Background = '#303744'; Foreground = '#F1F5F9'; Border = '#414A59'
HoverBackground = '#3B4555'; PressedBackground = '#485365'
DisabledBackground = '#292E38'; DisabledForeground = '#7F8999'
}
PrimaryButton = @{
Background = '#3B82F6'; Foreground = '#FFFFFF'; Border = '#3B82F6'
HoverBackground = '#2563EB'; PressedBackground = '#1D4ED8'
DisabledBackground = '#344A6A'; DisabledForeground = '#9AAAC1'
}
DangerButton = @{
Background = '#EF4444'; Foreground = '#FFFFFF'; Border = '#EF4444'
HoverBackground = '#DC2626'; PressedBackground = '#B91C1C'
DisabledBackground = '#59383B'; DisabledForeground = '#BBA0A2'
}
}
+29
View File
@@ -0,0 +1,29 @@
@{
Background = '#D1D5DB'
Panel = '#E5E7EB'
PanelAlt = '#F1F3F5'
TableHeader = '#D1D5DB'
TableRowEven = '#E5E7EB'
TableRowOdd = '#C9CED6'
Text = '#1E293B'
Secondary = '#475569'
Accent = '#2563EB'
Success = '#16A34A'
Border = '#AEB6C2'
Danger = '#DC2626'
Button = @{
Background = '#E5E7EB'; Foreground = '#1E293B'; Border = '#AEB6C2'
HoverBackground = '#D1D5DB'; PressedBackground = '#C2C8D0'
DisabledBackground = '#E5E7EB'; DisabledForeground = '#7B8492'
}
PrimaryButton = @{
Background = '#2563EB'; Foreground = '#FFFFFF'; Border = '#2563EB'
HoverBackground = '#1D4ED8'; PressedBackground = '#1E40AF'
DisabledBackground = '#C7D8F8'; DisabledForeground = '#F8FAFC'
}
DangerButton = @{
Background = '#DC2626'; Foreground = '#FFFFFF'; Border = '#DC2626'
HoverBackground = '#B91C1C'; PressedBackground = '#991B1B'
DisabledBackground = '#F2C5C5'; DisabledForeground = '#FFF7F7'
}
}