128 lines
6.1 KiB
PowerShell
128 lines
6.1 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'
|
|
|
|
$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 { }
|
|
}
|
|
|