xetup/scripts/12-windows-update.ps1
Filip Zubik 7e6095d1bd Fixes, Windows Update (step 12), auto-reboot, PS window hide
- Write-Log creates C:\Windows\Setup\Scripts\ automatically (was failing on fresh install)
- Step 12: PSWindowsUpdate first pass + X9-WindowsUpdate scheduled task for post-reboot rounds
  (handles typical 2-3 reboot cycles on fresh Windows, task self-deletes when up to date)
- GUI summary: 60s countdown auto-reboot with "Restartovat ted" / "Zrusit restart" buttons
- runner: HideWindow=true prevents PS console from appearing over GUI
- runner: skipPSNoiseLine filters PS error metadata (CategoryInfo, FullyQualifiedErrorId etc.)
- web: fix curl command to include https:// prefix
2026-04-16 14:49:41 +02:00

115 lines
5 KiB
PowerShell

<#
.SYNOPSIS
Installs all available Windows Updates via PSWindowsUpdate module.
.DESCRIPTION
First pass: installs all currently available updates without rebooting.
Then registers a scheduled task "X9-WindowsUpdate" that runs on every
logon (as SYSTEM) until no more updates are found - handles the typical
2-3 reboot cycles required on a fresh Windows installation.
Operator workflow:
1. xetup completes all steps
2. Operator reboots manually
3. On each subsequent logon the scheduled task runs another update pass
4. Task removes itself automatically when system is fully up to date
.ITEMS
nainstalovat-pswindowsupdate-modul: Installs NuGet provider and PSWindowsUpdate module from PSGallery.
spustit-prvni-kolo-windows-update: First update pass without reboot - installs all currently available updates.
registrovat-scheduled-task-pro-dalsi-kola: Registers X9-WindowsUpdate scheduled task that runs on logon, handles post-reboot update rounds, and self-deletes when no more updates are found.
#>
param(
[object]$Config,
[string]$LogFile
)
$ErrorActionPreference = "Continue"
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$line = "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message"
$null = New-Item -ItemType Directory -Force -Path (Split-Path $LogFile -Parent) -ErrorAction SilentlyContinue
Add-Content -Path $LogFile -Value $line -Encoding UTF8
Write-Output $line
}
Write-Log "=== Step 12 - Windows Update ===" -Level STEP
# -----------------------------------------------------------------------
# 1. NuGet provider + PSWindowsUpdate module
# -----------------------------------------------------------------------
Write-Log "Setting up PSWindowsUpdate module..." -Level INFO
try {
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope AllUsers | Out-Null
$existing = Get-Module -ListAvailable -Name PSWindowsUpdate | Select-Object -First 1
if ($existing) {
Write-Log " PSWindowsUpdate $($existing.Version) already installed" -Level INFO
} else {
Install-Module -Name PSWindowsUpdate -Force -Scope AllUsers -AllowClobber | Out-Null
Write-Log " PSWindowsUpdate installed" -Level OK
}
Import-Module PSWindowsUpdate -Force
} catch {
Write-Log " Module setup failed: $_" -Level ERROR
exit 1
}
# -----------------------------------------------------------------------
# 2. First update pass (no reboot)
# -----------------------------------------------------------------------
Write-Log "Running first Windows Update pass..." -Level INFO
try {
$result = Install-WindowsUpdate -AcceptAll -IgnoreReboot -Verbose 2>&1
$installed = @($result | Where-Object { $_ -match 'KB\d+|Downloaded|Installed' })
if ($installed.Count -gt 0) {
$result | Where-Object { "$_" -match '\S' } | ForEach-Object { Write-Log " $_" -Level INFO }
Write-Log " First pass complete - reboot required for remaining rounds" -Level OK
} else {
Write-Log " System already up to date" -Level OK
}
} catch {
Write-Log " First pass failed: $_" -Level ERROR
}
# -----------------------------------------------------------------------
# 3. Scheduled task for post-reboot update rounds (self-deleting)
# -----------------------------------------------------------------------
Write-Log "Registering post-reboot update task..." -Level INFO
$taskName = "X9-WindowsUpdate"
# PowerShell block that runs on each logon until no more updates found
$updateScript = @'
Import-Module PSWindowsUpdate -Force -ErrorAction Stop
$updates = Get-WindowsUpdate -AcceptAll -IgnoreReboot
if ($updates) {
Install-WindowsUpdate -AcceptAll -IgnoreReboot | Out-File "C:\Windows\Setup\Scripts\wu-pass-$(Get-Date -Format 'yyyyMMdd-HHmmss').log" -Encoding UTF8
} else {
# No more updates - remove this task
Unregister-ScheduledTask -TaskName "X9-WindowsUpdate" -Confirm:$false
}
'@
try {
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command `"$updateScript`""
$trigger = New-ScheduledTaskTrigger -AtLogOn
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Hours 2) `
-MultipleInstances IgnoreNew
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest
# Remove existing task first (idempotent)
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger `
-Settings $settings -Principal $principal -Force | Out-Null
Write-Log " Task '$taskName' registered - runs on each logon until fully updated" -Level OK
} catch {
Write-Log " Failed to register scheduled task: $_" -Level WARN
Write-Log " Manual Windows Update rounds will be needed after reboot" -Level WARN
}
Write-Log "Step 12 - Windows Update complete" -Level OK
Write-Log " ACTION REQUIRED: Reboot the machine to complete remaining update rounds" -Level WARN