From f91039b946d5810cbe6a5398e6d83208a201ec5e Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 10 Jun 2026 00:52:25 +0200 Subject: [PATCH] fix(toolchain): disable WU scan tasks via cmdlets, not schtasks.exe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- template/Install-CIToolchain-WinBuild2022.ps1 | 9 ++++++++- template/Install-CIToolchain-WinBuild2025.ps1 | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/template/Install-CIToolchain-WinBuild2022.ps1 b/template/Install-CIToolchain-WinBuild2022.ps1 index a45b31f..b175ffd 100644 --- a/template/Install-CIToolchain-WinBuild2022.ps1 +++ b/template/Install-CIToolchain-WinBuild2022.ps1 @@ -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' diff --git a/template/Install-CIToolchain-WinBuild2025.ps1 b/template/Install-CIToolchain-WinBuild2025.ps1 index 82ef2b5..d598193 100644 --- a/template/Install-CIToolchain-WinBuild2025.ps1 +++ b/template/Install-CIToolchain-WinBuild2025.ps1 @@ -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'