Fix WinRM restart: avoid UTF-8 BOM PowerShell parse error.

Run scripts via -File (UTF-8 no BOM) and Base64 ScriptBlock, using official stopcontainer/startcontainer for MF restart.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-24 08:36:10 +02:00
co-authored by Cursor
parent fe1988cdc7
commit cfbf80ecbf
2 changed files with 104 additions and 94 deletions
@@ -60,8 +60,10 @@ public sealed class SonicConnection
: WinRmContainerListScript;
/// <summary>
/// Echter Neustart mit Prozess-Verifikation (sichtbar in SMC):
/// alte PIDs müssen weg, neue PIDs müssen erscheinen sonst Fehler.
/// Offizieller MF-Container-Neustart laut Aurea CX Messenger Doku:
/// SonicHome\bin\stopcontainer.bat Domain.Container
/// SonicHome\bin\startcontainer.bat Domain.Container
/// Danach Prozess-Verifikation (alte PIDs weg, neue PIDs da).
/// </summary>
public const string DefaultRestartScript =
"""
@@ -69,14 +71,10 @@ public sealed class SonicConnection
$sonicHome = '{sonicHome}'
$domain = '{domain}'
$container = '{container}'
$connectionUrl = '{connectionUrl}'
$username = '{username}'
$password = '{password}'
$bin = Join-Path $sonicHome 'bin'
$stopBat = Join-Path $bin 'stopcontainer.bat'
$startBat = Join-Path $bin 'startcontainer.bat'
$esbAdmin = Join-Path $bin 'esbadmin.bat'
# Kurzname = Container (z.B. DE-Test), Full = Domain.Container (z.B. proalpha-test.DE-Test)
$shortName = if ($container -like '*.*') { ($container -split '\.', 2)[1] } else { $container }
@@ -120,46 +118,40 @@ public sealed class SonicConnection
return ,@()
}
function Invoke-ContainerBat([string]$bat, [string]$name) {
if (-not (Test-Path -LiteralPath $bat)) {
throw "Sonic BAT fehlt: $bat (SonicHome pruefen)"
}
$arg = '/c "' + $bat + '" "' + $name + '"'
$p = Start-Process -FilePath 'cmd.exe' -ArgumentList $arg -Wait -PassThru -NoNewWindow
return [int]$p.ExitCode
}
Write-Output "INFO:Domain=$domain Container=$shortName Full=$fullName"
Write-Output "INFO:RestartVia=stopcontainer/startcontainer (MF Container)"
$before = @(Get-ContainerPids)
Write-Output "INFO:PIDsVorher=$($before -join ',')"
Write-Output "INFO:PIDsBefore=$($before -join ',')"
if ($before.Count -eq 0) {
Write-Output "WARN:Kein laufender Java/Sonic-Prozess für '$shortName' gefunden Stop ggf. schon offline; starte trotzdem."
Write-Output "WARN:No running Java/Sonic process for '$shortName' - starting anyway"
}
# 1) Optional: esbadmin (SMC-kompatibel über Domain Manager)
if (Test-Path -LiteralPath $esbAdmin) {
Write-Output "INFO:Versuche esbadmin Stop/Start"
$scriptText = "connect $domain $connectionUrl $username $password`r`nstop container $shortName`r`nstart container $shortName`r`nexit`r`n"
$tmp = [System.IO.Path]::GetTempFileName() + '.txt'
Set-Content -LiteralPath $tmp -Value $scriptText -Encoding ASCII
try {
$p = Start-Process -FilePath 'cmd.exe' -ArgumentList @('/c', "`"$esbAdmin`" < `"$tmp`"") -Wait -PassThru -NoNewWindow
Write-Output "INFO:esbadmin ExitCode=$($p.ExitCode)"
}
finally {
Remove-Item -LiteralPath $tmp -Force -ErrorAction SilentlyContinue
}
Start-Sleep -Seconds 5
# 1) Offiziell: stopcontainer.bat Domain.Container (danach Kurzname als Fallback)
$stopOk = $false
foreach ($n in @($fullName, $shortName)) {
Write-Output "INFO:stopcontainer $n"
$code = Invoke-ContainerBat -bat $stopBat -name $n
Write-Output "INFO:stopcontainer ExitCode=$code Name=$n"
if ($code -eq 0) { $stopOk = $true; break }
}
# 2) stopcontainer.bat
if (Test-Path -LiteralPath $stopBat) {
foreach ($n in @($fullName, $shortName)) {
Write-Output "INFO:stopcontainer $n"
$sp = Start-Process -FilePath 'cmd.exe' -ArgumentList @('/c', "`"$stopBat`" `"$n`"") -Wait -PassThru -NoNewWindow
Write-Output "INFO:stopcontainer ExitCode=$($sp.ExitCode) Name=$n"
}
}
else {
Write-Output "WARN:stopcontainer.bat fehlt: $stopBat"
if (-not $stopOk) {
Write-Output "WARN:stopcontainer non-zero; will force-stop remaining PIDs if any"
}
Start-Sleep -Seconds 3
$still = @(Get-ContainerPids)
# 3) Harter Stop der alten PIDs sonst sieht SMC oft keinen Neustart
# 2) Force-Stop falls BAT den Prozess nicht beendet (sonst kein echter Restart in SMC)
if ($still.Count -gt 0) {
Write-Output "INFO:Force-Stop PIDs=$($still -join ',')"
foreach ($procId in $still) {
@@ -169,41 +161,36 @@ public sealed class SonicConnection
if ($before.Count -gt 0) {
if (-not (Wait-PidsGone -pids $before -seconds 45)) {
throw "Container-Prozess läuft noch nach Stop (PIDs=$($before -join ',')). SMC würde keinen Stop sehen."
throw "Container process still running after stop (PIDs=$($before -join ','))"
}
Write-Output "INFO:Alte PIDs beendet"
Write-Output "INFO:Old PIDs gone"
}
Start-Sleep -Seconds 3
# 4) Start
if (-not (Test-Path -LiteralPath $startBat)) {
throw "startcontainer.bat nicht gefunden: $startBat (SonicHome prüfen)"
}
# 3) Offiziell: startcontainer.bat Domain.Container
$started = $false
foreach ($n in @($fullName, $shortName)) {
Write-Output "INFO:startcontainer $n"
$st = Start-Process -FilePath 'cmd.exe' -ArgumentList @('/c', "`"$startBat`" `"$n`"") -Wait -PassThru -NoNewWindow
Write-Output "INFO:startcontainer ExitCode=$($st.ExitCode) Name=$n"
if ($st.ExitCode -eq 0) { $started = $true; break }
$code = Invoke-ContainerBat -bat $startBat -name $n
Write-Output "INFO:startcontainer ExitCode=$code Name=$n"
if ($code -eq 0) { $started = $true; break }
}
if (-not $started) {
throw "startcontainer fehlgeschlagen für $fullName / $shortName"
throw "startcontainer failed for $fullName / $shortName"
}
$after = @(Wait-NewPids -oldPids $before -seconds 60)
if ($after.Count -eq 0) {
# falls Prozess mit gleicher PID-Liste zurückkam: mindestens irgendeinen Treffer verlangen
$any = @(Get-ContainerPids)
if ($any.Count -eq 0) {
throw "Nach Start kein Prozess für Container '$shortName' sichtbar. In SMC prüfen / SonicHome & ContainerName prüfen."
throw "After start no process for container '$shortName'. Check SMC / SonicHome / ContainerName."
}
Write-Output "INFO:PIDsNachher=$($any -join ',')"
Write-Output "INFO:PIDsAfter=$($any -join ',')"
}
else {
Write-Output "INFO:PIDsNachher=$($after -join ',')"
Write-Output "INFO:PIDsAfter=$($after -join ',')"
}
Write-Output "OK:ContainerRestartVerified Domain=$domain Container=$shortName"