fix(toolchain): pin WU disabled across the DISM /ResetBase window
The disk-cleanup function stopped wuauserv before DISM /StartComponentCleanup /ResetBase but only re-enforced Start=4 AFTER it. /ResetBase drives heavy CBS servicing (TiWorker); during that window WaaSMedicSvc woke, flipped wuauserv Start back to Manual, and a "Schedule Scan" task started it. If the pass was interrupted there (reboot/crash), the template was left with WU running and Manual startup — a half-prepared state where Windows Update keeps firing on a supposedly-locked-down build template. Move the lockdown ahead of DISM: set wuauserv Start=4, apply the WaaSMedicSvc registry write-deny ACL (the only reliable lever — the service is protected and cannot itself be disabled), and disable the WindowsUpdate / UpdateOrchestrator scan tasks, all BEFORE /ResetBase rather than only after. The post-DISM re-enforce stays as a belt-and-suspenders check. Applied identically to the WinBuild2025 and WinBuild2022 toolchains.
This commit is contained in:
@@ -253,6 +253,41 @@ function Invoke-DiskCleanup {
|
|||||||
foreach ($svc in 'wuauserv', 'UsoSvc', 'bits', 'dosvc', 'TrustedInstaller') {
|
foreach ($svc in 'wuauserv', 'UsoSvc', 'bits', 'dosvc', 'TrustedInstaller') {
|
||||||
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
|
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Pin Windows Update down for the WHOLE DISM /ResetBase window below. /ResetBase
|
||||||
|
# drives heavy CBS servicing (TiWorker); with wuauserv merely *stopped* and no
|
||||||
|
# ACL yet, WaaSMedicSvc wakes, flips wuauserv Start back to Manual, and a
|
||||||
|
# "Schedule Scan" task starts it mid-cleanup — so an interruption here leaves WU
|
||||||
|
# running (exactly the half-prepared state seen on stuck templates). Force
|
||||||
|
# Start=4, deny WaaSMedicSvc the registry write, and disable the scan tasks
|
||||||
|
# BEFORE DISM, not only in the re-enforce after it.
|
||||||
|
Set-Service -Name wuauserv -StartupType Disabled -ErrorAction SilentlyContinue
|
||||||
|
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\wuauserv' `
|
||||||
|
-Name Start -Value 4 -Type DWord -Force -ErrorAction SilentlyContinue
|
||||||
|
try {
|
||||||
|
$svcRegPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\wuauserv'
|
||||||
|
$acl = Get-Acl $svcRegPath
|
||||||
|
$denyRule = New-Object System.Security.AccessControl.RegistryAccessRule(
|
||||||
|
([System.Security.Principal.NTAccount]'NT SERVICE\WaaSMedicSvc'),
|
||||||
|
[System.Security.AccessControl.RegistryRights]'SetValue,CreateSubKey,WriteKey',
|
||||||
|
[System.Security.AccessControl.InheritanceFlags]::None,
|
||||||
|
[System.Security.AccessControl.PropagationFlags]::None,
|
||||||
|
[System.Security.AccessControl.AccessControlType]::Deny
|
||||||
|
)
|
||||||
|
$acl.AddAccessRule($denyRule)
|
||||||
|
Set-Acl $svcRegPath $acl
|
||||||
|
Write-Host "wuauserv: WaaSMedicSvc write-deny ACL applied (pre-DISM)."
|
||||||
|
} catch {
|
||||||
|
Write-Warning "wuauserv pre-DISM ACL deny skipped (non-fatal): $_"
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
$sdDownload = 'C:\Windows\SoftwareDistribution\Download'
|
$sdDownload = 'C:\Windows\SoftwareDistribution\Download'
|
||||||
Remove-Item $sdDownload -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item $sdDownload -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
New-Item -ItemType Directory -Path $sdDownload -Force | Out-Null
|
New-Item -ItemType Directory -Path $sdDownload -Force | Out-Null
|
||||||
|
|||||||
@@ -254,6 +254,41 @@ function Invoke-DiskCleanup {
|
|||||||
foreach ($svc in 'wuauserv', 'UsoSvc', 'bits', 'dosvc', 'TrustedInstaller') {
|
foreach ($svc in 'wuauserv', 'UsoSvc', 'bits', 'dosvc', 'TrustedInstaller') {
|
||||||
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
|
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Pin Windows Update down for the WHOLE DISM /ResetBase window below. /ResetBase
|
||||||
|
# drives heavy CBS servicing (TiWorker); with wuauserv merely *stopped* and no
|
||||||
|
# ACL yet, WaaSMedicSvc wakes, flips wuauserv Start back to Manual, and a
|
||||||
|
# "Schedule Scan" task starts it mid-cleanup — so an interruption here leaves WU
|
||||||
|
# running (exactly the half-prepared state seen on stuck templates). Force
|
||||||
|
# Start=4, deny WaaSMedicSvc the registry write, and disable the scan tasks
|
||||||
|
# BEFORE DISM, not only in the re-enforce after it.
|
||||||
|
Set-Service -Name wuauserv -StartupType Disabled -ErrorAction SilentlyContinue
|
||||||
|
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\wuauserv' `
|
||||||
|
-Name Start -Value 4 -Type DWord -Force -ErrorAction SilentlyContinue
|
||||||
|
try {
|
||||||
|
$svcRegPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\wuauserv'
|
||||||
|
$acl = Get-Acl $svcRegPath
|
||||||
|
$denyRule = New-Object System.Security.AccessControl.RegistryAccessRule(
|
||||||
|
([System.Security.Principal.NTAccount]'NT SERVICE\WaaSMedicSvc'),
|
||||||
|
[System.Security.AccessControl.RegistryRights]'SetValue,CreateSubKey,WriteKey',
|
||||||
|
[System.Security.AccessControl.InheritanceFlags]::None,
|
||||||
|
[System.Security.AccessControl.PropagationFlags]::None,
|
||||||
|
[System.Security.AccessControl.AccessControlType]::Deny
|
||||||
|
)
|
||||||
|
$acl.AddAccessRule($denyRule)
|
||||||
|
Set-Acl $svcRegPath $acl
|
||||||
|
Write-Host "wuauserv: WaaSMedicSvc write-deny ACL applied (pre-DISM)."
|
||||||
|
} catch {
|
||||||
|
Write-Warning "wuauserv pre-DISM ACL deny skipped (non-fatal): $_"
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
$sdDownload = 'C:\Windows\SoftwareDistribution\Download'
|
$sdDownload = 'C:\Windows\SoftwareDistribution\Download'
|
||||||
Remove-Item $sdDownload -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item $sdDownload -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
New-Item -ItemType Directory -Path $sdDownload -Force | Out-Null
|
New-Item -ItemType Directory -Path $sdDownload -Force | Out-Null
|
||||||
|
|||||||
Reference in New Issue
Block a user