fix(template): make prepare-win robust without prior Deploy run

- WinRM MaxProcessesPerShell: apply 100 if below threshold before asserting
- DesktopHeap SharedSection: apply 4096 KB registry value if below threshold before asserting
- Replace cleanmgr (hangs in WinRM Session 0, no window station) with direct
  PowerShell cleanup for dumps, WER files and Recycle Bin; DISM already covers
  component store and WU cache
- vcpkg git clone/checkout: wrap with EAP=Continue to suppress PS5.1
  NativeCommandError on git stderr (gotcha #3 from AGENTS.md)
- template.py: filter CI_EXITCODE:N marker from displayed output
- ci-static-ip.ps1: switch from vmware-rpctool (removed in recent Tools) to
  vmtoolsd --cmd; use temp-file redirect to capture output from native cmd

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 22:03:49 +02:00
parent faf5b9e29b
commit f090365d57
4 changed files with 84 additions and 99 deletions
+23 -40
View File
@@ -239,47 +239,17 @@ function Assert-Hash {
function Invoke-DiskCleanup {
Write-Step "Cleaning up disk"
# 1. Windows Disk Cleanup (cleanmgr) — run with /sagerun:1 using preset flags
# First register the flags via /sageset:1 in the registry (silent, no UI)
$cleanKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches'
$sageset = 1
$cleanCategories = @(
'Active Setup Temp Folders',
'BranchCache',
'Downloaded Program Files',
'Internet Cache Files',
'Memory Dump Files',
'Old ChkDsk Files',
'Previous Installations',
'Recycle Bin',
'Service Pack Cleanup',
'Setup Log Files',
'System error memory dump files',
'System error minidump files',
'Temporary Files',
'Temporary Setup Files',
'Thumbnail Cache',
'Update Cleanup',
'Upgrade Discarded Files',
'Windows Defender',
'Windows Error Reporting Archive Files',
'Windows Error Reporting Files',
'Windows Error Reporting Queue Files',
'Windows Error Reporting Temp Files',
'Windows ESD installation files',
'Windows Upgrade Log Files'
)
foreach ($cat in $cleanCategories) {
$keyPath = "$cleanKey\$cat"
if (Test-Path $keyPath) {
Set-ItemProperty -Path $keyPath -Name "StateFlags$('{0:D4}' -f $sageset)" -Value 2 -Type DWord -Force -ErrorAction SilentlyContinue
}
}
Write-Host "Running cleanmgr /sagerun:$sageset (may take a few minutes)..."
$proc = Start-Process -FilePath 'cleanmgr.exe' -ArgumentList "/sagerun:$sageset" -Wait -PassThru
Write-Host "cleanmgr exited (code $($proc.ExitCode))."
# cleanmgr.exe requires an interactive window station — hangs in WinRM Session 0.
# Replicate the relevant categories with direct PowerShell cleanup instead.
Write-Host "Clearing memory dumps..."
Remove-Item 'C:\Windows\Minidump\*' -Force -Recurse -ErrorAction SilentlyContinue
Remove-Item 'C:\Windows\memory.dmp' -Force -ErrorAction SilentlyContinue
Write-Host "Clearing Windows Error Reporting files..."
Remove-Item 'C:\ProgramData\Microsoft\Windows\WER\*' -Force -Recurse -ErrorAction SilentlyContinue
Write-Host "Clearing Recycle Bin..."
Clear-RecycleBin -DriveLetter C -Force -ErrorAction SilentlyContinue
# 2. Clear Windows Update cache
# Clear Windows Update cache
Write-Host "Stopping WU-adjacent services before cache clear..."
foreach ($svc in 'wuauserv', 'UsoSvc', 'bits', 'dosvc', 'TrustedInstaller') {
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
@@ -451,9 +421,18 @@ Assert-Step 'WinRM' 'Shell MaxMemoryPerShellMB >= 2048' {
Assert-Step 'WinRM' 'Plugin Microsoft.PowerShell MaxMemoryPerShellMB >= 2048' {
[int](Get-Item 'WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB').Value -ge 2048
}
if ([int](Get-Item WSMan:\localhost\Shell\MaxProcessesPerShell -ErrorAction SilentlyContinue).Value -lt 100) {
Set-Item WSMan:\localhost\Shell\MaxProcessesPerShell 100 -Force
}
Assert-Step 'WinRM' 'MaxProcessesPerShell >= 100' {
[int](Get-Item WSMan:\localhost\Shell\MaxProcessesPerShell).Value -ge 100
}
$_subsysKey = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems'
$_subsysCur = (Get-ItemProperty $_subsysKey -Name Windows).Windows
if (-not ($_subsysCur -match 'SharedSection=\d+,\d+,(\d+)') -or [int]$Matches[1] -lt 4096) {
$subsysNew = $_subsysCur -replace 'SharedSection=(\d+),(\d+),\d+', 'SharedSection=$1,$2,4096'
Set-ItemProperty $_subsysKey -Name Windows -Value $subsysNew
}
Assert-Step 'DesktopHeap' 'SharedSection non-interactive >= 4096 KB' {
$w = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems' -Name Windows).Windows
if ($w -match 'SharedSection=\d+,\d+,(\d+)') { [int]$Matches[1] -ge 4096 } else { $false }
@@ -1601,11 +1580,15 @@ if (Test-Path $vcpkgExe) {
$cloneArgs += '--depth'
$cloneArgs += '1'
}
$savedEap = $ErrorActionPreference; $ErrorActionPreference = 'Continue'
& $gitBin.Source @cloneArgs 2>&1 | Write-Host
$ErrorActionPreference = $savedEap
if ($LASTEXITCODE -ne 0) { throw "vcpkg git clone failed (exit $LASTEXITCODE)." }
if ($VcpkgRef -ne '') {
Write-Host "Checking out vcpkg ref: $VcpkgRef"
$savedEap = $ErrorActionPreference; $ErrorActionPreference = 'Continue'
& $gitBin.Source -C $vcpkgDir checkout $VcpkgRef 2>&1 | Write-Host
$ErrorActionPreference = $savedEap
if ($LASTEXITCODE -ne 0) { throw "vcpkg checkout '$VcpkgRef' failed (exit $LASTEXITCODE)." }
}
Write-Host "Bootstrapping vcpkg (-disableMetrics)..."