fix(toolchain): disable WU scan tasks via cmdlets, not schtasks.exe

schtasks.exe /Change on a non-existent task writes to stderr and exits 1.
Inside the disk-cleanup function (EAP=Stop, wrapped by the exit-code-sensitive
prepare-win cleanup invoker), that leaked $LASTEXITCODE=1 all the way to the
result marker — DISM runs via Start-Process and does not reset it — so the
step failed with "Disk cleanup failed (exit 1)" even though everything worked.
On a freshly-deployed WS2025 the UpdateOrchestrator "Schedule Scan" task does
not exist, so this fired every run.

Replace the schtasks loop with Get-ScheduledTask | Disable-ScheduledTask,
which no-ops silently on a missing task and sets no process exit code.

Follow-up to fb5de6f; applied to both toolchains.
This commit is contained in:
2026-06-10 00:52:25 +02:00
parent fb5de6f59f
commit f91039b946
2 changed files with 16 additions and 2 deletions
@@ -280,12 +280,19 @@ function Invoke-DiskCleanup {
} catch {
Write-Warning "wuauserv pre-DISM ACL deny skipped (non-fatal): $_"
}
# Use the ScheduledTasks cmdlets (not schtasks.exe): a missing task makes
# schtasks write to stderr and exit 1, which — under EAP=Stop and the
# exit-code-sensitive cleanup wrapper — leaks $LASTEXITCODE=1 and fails the
# whole step. The cmdlets just no-op silently when the task is absent.
foreach ($t in @(
'\Microsoft\Windows\WindowsUpdate\Scheduled Start',
'\Microsoft\Windows\UpdateOrchestrator\Schedule Scan',
'\Microsoft\Windows\UpdateOrchestrator\Schedule Scan Static Task'
)) {
schtasks /Change /TN $t /Disable 2>&1 | Out-Null
$leaf = Split-Path $t -Leaf
$path = (Split-Path $t -Parent) + '\'
Get-ScheduledTask -TaskPath $path -TaskName $leaf -ErrorAction SilentlyContinue |
Disable-ScheduledTask -ErrorAction SilentlyContinue | Out-Null
}
$sdDownload = 'C:\Windows\SoftwareDistribution\Download'
@@ -281,12 +281,19 @@ function Invoke-DiskCleanup {
} catch {
Write-Warning "wuauserv pre-DISM ACL deny skipped (non-fatal): $_"
}
# Use the ScheduledTasks cmdlets (not schtasks.exe): a missing task makes
# schtasks write to stderr and exit 1, which — under EAP=Stop and the
# exit-code-sensitive cleanup wrapper — leaks $LASTEXITCODE=1 and fails the
# whole step. The cmdlets just no-op silently when the task is absent.
foreach ($t in @(
'\Microsoft\Windows\WindowsUpdate\Scheduled Start',
'\Microsoft\Windows\UpdateOrchestrator\Schedule Scan',
'\Microsoft\Windows\UpdateOrchestrator\Schedule Scan Static Task'
)) {
schtasks /Change /TN $t /Disable 2>&1 | Out-Null
$leaf = Split-Path $t -Leaf
$path = (Split-Path $t -Parent) + '\'
Get-ScheduledTask -TaskPath $path -TaskName $leaf -ErrorAction SilentlyContinue |
Disable-ScheduledTask -ErrorAction SilentlyContinue | Out-Null
}
$sdDownload = 'C:\Windows\SoftwareDistribution\Download'