Files
DeployCenter/Modules/VNC.psm1
T
benoit 8d5014b4aa Ajout de la partie application des changements sur le disque
Ajout de l'installation de Windows
Correction du chargement des images iso.
Correction de la définition de la taille de WinRE.
2026-10-17 03:56:53 +02:00

140 lines
7.8 KiB
PowerShell

# 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'
if ([string]::IsNullOrWhiteSpace($script:DeployIPv4)) {
& $script:SourceLogAction 'Aucune adresse IPv4 de déploiement détectée.' 'WARNING'
}
if (-not (Test-Path -LiteralPath $sourceExe -PathType Leaf)) {
& $script:SourceLogAction "UltraVNC non démarré : exécutable absent ($sourceExe)." 'WARNING'
Write-DeployInventory -InventoryDir $script:InventoryDir -InventoryFile $script:InventoryFile -HardwareInfo $script:HardwareInventory -DeploymentIPv4 $script:DeployIPv4 -VncPassword $script:VncPassword -LogAction $script:SourceLogAction
return
}
if (-not (Test-Path -LiteralPath $passwordTool -PathType Leaf)) {
& $script:SourceLogAction "UltraVNC non démarré : createpassword64.exe absent ($passwordTool)." 'WARNING'
Write-DeployInventory -InventoryDir $script:InventoryDir -InventoryFile $script:InventoryFile -HardwareInfo $script:HardwareInventory -DeploymentIPv4 $script:DeployIPv4 -VncPassword $script:VncPassword -LogAction $script:SourceLogAction
return
}
if (-not (Test-Path -LiteralPath $sourceIni -PathType Leaf)) {
& $script:SourceLogAction "UltraVNC non démarré : fichier absent ($sourceIni)." 'WARNING'
Write-DeployInventory -InventoryDir $script:InventoryDir -InventoryFile $script:InventoryFile -HardwareInfo $script:HardwareInventory -DeploymentIPv4 $script:DeployIPv4 -VncPassword $script:VncPassword -LogAction $script:SourceLogAction
return
}
$vncStage = 'préparation du dossier temporaire'
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
$vncStage = "copie des fichiers depuis $sourceVnc vers $script:VncDirectory"
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é.
$vncStage = 'désactivation du pare-feu WinPE'
$wpeutil = Join-Path $env:WINDIR 'System32\wpeutil.exe'
if (-not (Test-Path -LiteralPath $wpeutil -PathType Leaf)) {
$wpeutil = 'wpeutil.exe'
}
$wpeutilOutput = @(& $wpeutil DisableFirewall 2>&1)
$wpeutilExitCode = $LASTEXITCODE
foreach ($outputLine in $wpeutilOutput) {
$outputText = [string]$outputLine
if (-not [string]::IsNullOrWhiteSpace($outputText)) {
& $script:SourceLogAction "wpeutil DisableFirewall : $outputText" 'INFO'
}
}
if ($wpeutilExitCode -ne 0) {
throw "wpeutil DisableFirewall a renvoyé le code $wpeutilExitCode."
}
& $script:SourceLogAction "Pare-feu WinPE désactivé à la demande de -Vnc (code wpeutil : $wpeutilExitCode)." 'WARNING'
# Force le mode portable : l'INI actif est celui placé à côté de winvnc.exe.
$vncStage = 'activation du mode portable UltraVNC'
$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.
$vncStage = 'génération du mot de passe UltraVNC'
$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'
$vncStage = 'démarrage du serveur UltraVNC'
$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
& $script:SourceLogAction "UltraVNC démarré. IP : $($script:DeployIPv4) ; mot de passe $passwordSource." 'SUCCESS'
} catch {
& $script:SourceLogAction "Échec du démarrage UltraVNC à l'étape '$vncStage' : $($_.Exception.Message)" 'ERROR'
$script:VncStarted = $false
$script:VncPassword = $null
}
Write-DeployInventory -InventoryDir $script:InventoryDir -InventoryFile $script:InventoryFile -HardwareInfo $script:HardwareInventory -DeploymentIPv4 $script:DeployIPv4 -VncPassword $script:VncPassword -LogAction $script:SourceLogAction
}
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 {
& $script:SourceLogAction "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 { }
}