kms-website: add consent-gated deep repair for wedged SXSMSI/1603 Office install
When the Office VL install fails with setup.exe 1603 (C2R 'SXSMSI' prereq) AND no reboot is pending AND the common causes are clean (verified via telemetry: msiserver healthy, EventLog running, no DisableMSI policy, no stale InProgress MSI, disk OK) AND a manual DISM/SFC + reboot did not help, the install subsystem itself is wedged. New Repair-OfficePrereq (consent-gated; $env:KMS_DEEP_REPAIR=1 to auto-consent) goes one level past DISM without uninstalling anything: re-registers the Windows Installer engine (msiexec /unregister + /regserver) and resets the servicing/update caches (SoftwareDistribution + catroot2), then prompts a restart and re-run. Offered automatically from Reinstall-OfficeVL on a 1603 with no pending reboot. ODT exit code now exposed via $script:OdtExitCode.
This commit is contained in:
parent
dfc83fbb0a
commit
b4927236cd
1 changed files with 43 additions and 1 deletions
|
|
@ -361,6 +361,7 @@ function Invoke-Odt([string]$configXml, [string]$stepMsg) {
|
||||||
Step $stepMsg
|
Step $stepMsg
|
||||||
$p = Start-Process -FilePath $setup -ArgumentList '/configure', "`"$cfg`"" -Wait -PassThru
|
$p = Start-Process -FilePath $setup -ArgumentList '/configure', "`"$cfg`"" -Wait -PassThru
|
||||||
$code = $p.ExitCode
|
$code = $p.ExitCode
|
||||||
|
$script:OdtExitCode = $code
|
||||||
# 0 = success, 3010 = success/reboot-required. Anything else is a real ODT
|
# 0 = success, 3010 = success/reboot-required. Anything else is a real ODT
|
||||||
# failure - surface the log tail (carries the error code) so we can diagnose.
|
# failure - surface the log tail (carries the error code) so we can diagnose.
|
||||||
if ($code -ne 0 -and $code -ne 3010) {
|
if ($code -ne 0 -and $code -ne 3010) {
|
||||||
|
|
@ -381,6 +382,42 @@ function Invoke-Odt([string]$configXml, [string]$stepMsg) {
|
||||||
finally { Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue }
|
finally { Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Deep repair for a wedged Office-install prerequisite (the C2R 'SXSMSI' check
|
||||||
|
# fails with 1603) when the common causes are clean AND DISM/SFC did not help.
|
||||||
|
# Goes one level past DISM: re-registers the Windows Installer engine and resets
|
||||||
|
# the servicing/update caches (SoftwareDistribution + catroot2) - which fixes
|
||||||
|
# MSI-engine / signature-catalog corruption that DISM/SFC leave untouched. It
|
||||||
|
# UNINSTALLS NOTHING. A restart is required afterwards. Consent-gated; set
|
||||||
|
# $env:KMS_DEEP_REPAIR=1 to auto-consent.
|
||||||
|
function Repair-OfficePrereq {
|
||||||
|
$msg = @"
|
||||||
|
The Office installer's prerequisite check keeps failing (SXSMSI / error 1603) and
|
||||||
|
the usual causes are clean (no pending reboot, Windows Installer healthy, disk OK,
|
||||||
|
no policy block). A DEEP REPAIR can fix the Windows install subsystem - it does NOT
|
||||||
|
uninstall anything:
|
||||||
|
* re-register the Windows Installer engine (msiexec /unregister + /regserver)
|
||||||
|
* reset the Windows servicing/update caches (SoftwareDistribution + catroot2)
|
||||||
|
A RESTART is required afterwards, then re-run this one-liner to install Office.
|
||||||
|
"@
|
||||||
|
if (-not (Approve $msg ([bool]$env:KMS_DEEP_REPAIR))) { Warn "Deep repair skipped."; return $false }
|
||||||
|
Send-Diag 'odt' 'deep-repair-start' (Get-OfficeState)
|
||||||
|
Step "Re-registering the Windows Installer engine"
|
||||||
|
Start-Process -FilePath 'msiexec.exe' -ArgumentList '/unregister' -Wait -ErrorAction SilentlyContinue
|
||||||
|
Start-Process -FilePath 'msiexec.exe' -ArgumentList '/regserver' -Wait -ErrorAction SilentlyContinue
|
||||||
|
Step "Resetting servicing/update caches (SoftwareDistribution, catroot2)"
|
||||||
|
foreach ($s in 'wuauserv', 'cryptSvc', 'bits', 'msiserver') { Stop-Service $s -Force -ErrorAction SilentlyContinue }
|
||||||
|
$stamp = Get-Date -Format 'yyyyMMddHHmmss'
|
||||||
|
foreach ($p in @("$env:WINDIR\SoftwareDistribution", "$env:WINDIR\System32\catroot2")) {
|
||||||
|
if (Test-Path $p) { Rename-Item -LiteralPath $p -NewName "$(Split-Path $p -Leaf).old-$stamp" -ErrorAction SilentlyContinue }
|
||||||
|
}
|
||||||
|
foreach ($s in 'cryptSvc', 'bits', 'wuauserv') { Start-Service $s -ErrorAction SilentlyContinue }
|
||||||
|
OK "Deep repair complete."
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "==> NOW restart the PC (Start -> Power -> RESTART, not Shut down), then re-run the one-liner." -ForegroundColor Yellow
|
||||||
|
Send-Diag 'odt' 'deep-repair-done' (Get-OfficeState)
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
function Reinstall-OfficeVL([string]$product, [string]$channel) {
|
function Reinstall-OfficeVL([string]$product, [string]$channel) {
|
||||||
# An Office-blocking pending reboot (CBS/WU, or an Office file-rename) fails the
|
# An Office-blocking pending reboot (CBS/WU, or an Office file-rename) fails the
|
||||||
# C2R 'SXSMSI' prereq with 1603. Stop before the ~3 GB download and tell the user
|
# C2R 'SXSMSI' prereq with 1603. Stop before the ~3 GB download and tell the user
|
||||||
|
|
@ -413,7 +450,12 @@ function Reinstall-OfficeVL([string]$product, [string]$channel) {
|
||||||
# Snapshot the pre-install state so a failure is debuggable even if the user
|
# Snapshot the pre-install state so a failure is debuggable even if the user
|
||||||
# aborts the ~3 GB download (the event ships before the install starts).
|
# aborts the ~3 GB download (the event ships before the install starts).
|
||||||
Send-Diag 'odt' 'preinstall-state' (Get-OfficeState)
|
Send-Diag 'odt' 'preinstall-state' (Get-OfficeState)
|
||||||
if (-not (Invoke-Odt $xml "Installing $product (multi-GB download + reinstall; several minutes)")) { return $false }
|
if (-not (Invoke-Odt $xml "Installing $product (multi-GB download + reinstall; several minutes)")) {
|
||||||
|
# SXSMSI/1603 with no pending reboot = the Windows install subsystem itself is
|
||||||
|
# wedged (survives DISM/SFC). Offer the deep repair, then reboot + re-run.
|
||||||
|
if ($script:OdtExitCode -eq 1603 -and -not (Test-OfficeRebootPending)) { Repair-OfficePrereq | Out-Null }
|
||||||
|
return $false
|
||||||
|
}
|
||||||
# setup.exe returning is NOT proof Office is on disk - verify it actually landed.
|
# setup.exe returning is NOT proof Office is on disk - verify it actually landed.
|
||||||
if (Wait-OfficeInstalled $product) { OK "$product installed"; return $true }
|
if (Wait-OfficeInstalled $product) { OK "$product installed"; return $true }
|
||||||
$reboot = Test-PendingReboot
|
$reboot = Test-PendingReboot
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue