# 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_) : 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 { } }