All checks were successful
release / build-and-release (push) Successful in 21s
When X9-WindowsUpdate finds no more updates: - Creates "! WU HOTOVO yyyy-MM-dd HH:mm.txt" on C:\Users\Public\Desktop - Locks the workstation via one-shot task running as adminx9 (login screen = unambiguous visual signal for the operator) - One-shot lock task self-deletes after 5 minutes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
157 lines
7.6 KiB
PowerShell
157 lines
7.6 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. Enable autologon for adminx9 (temporary - disabled when updates complete)
|
|
# -----------------------------------------------------------------------
|
|
Write-Log "Enabling temporary autologon for adminx9..." -Level INFO
|
|
|
|
$winlogonPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
|
|
try {
|
|
Set-ItemProperty -Path $winlogonPath -Name "AutoAdminLogon" -Value "1" -Type String -Force
|
|
Set-ItemProperty -Path $winlogonPath -Name "DefaultUserName" -Value "adminx9" -Type String -Force
|
|
Set-ItemProperty -Path $winlogonPath -Name "DefaultPassword" -Value "" -Type String -Force
|
|
Set-ItemProperty -Path $winlogonPath -Name "DefaultDomainName" -Value "." -Type String -Force
|
|
# Safety cap: max 10 automatic logons in case the task fails to clean up
|
|
Set-ItemProperty -Path $winlogonPath -Name "AutoLogonCount" -Value 10 -Type DWord -Force
|
|
Write-Log " Autologon enabled (adminx9, max 10 rounds)" -Level OK
|
|
} catch {
|
|
Write-Log " Failed to enable autologon: $_" -Level WARN
|
|
Write-Log " Windows Update rounds will require manual login after each reboot" -Level WARN
|
|
}
|
|
|
|
# -----------------------------------------------------------------------
|
|
# 4. 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.
|
|
# When done: disables autologon and removes itself.
|
|
$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 - disable autologon and clean up
|
|
$wl = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
|
|
Set-ItemProperty -Path $wl -Name "AutoAdminLogon" -Value "0" -Type String -Force
|
|
Remove-ItemProperty -Path $wl -Name "DefaultPassword" -ErrorAction SilentlyContinue
|
|
Remove-ItemProperty -Path $wl -Name "AutoLogonCount" -ErrorAction SilentlyContinue
|
|
|
|
# Leave a visible marker on the shared Desktop so the operator knows it's done
|
|
$ts = Get-Date -Format "yyyy-MM-dd HH:mm"
|
|
$doneMsg = "Windows Update dokoncen: $ts`r`nStroj je plne aktualizovan a pripraven k predani klientovi."
|
|
[System.IO.File]::WriteAllText(
|
|
"C:\Users\Public\Desktop\! WU HOTOVO $ts.txt",
|
|
$doneMsg,
|
|
[System.Text.Encoding]::UTF8
|
|
)
|
|
|
|
# Lock the workstation - login screen = clear visual signal for the operator.
|
|
# Runs as adminx9 (interactive session) via a one-shot task, self-deletes after 5 min.
|
|
$lockAction = New-ScheduledTaskAction -Execute "rundll32.exe" -Argument "user32.dll,LockWorkStation"
|
|
$lockTrigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddSeconds(5)
|
|
$lockPrincipal = New-ScheduledTaskPrincipal -UserId "adminx9" -LogonType Interactive -RunLevel Limited
|
|
$lockSettings = New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter (New-TimeSpan -Minutes 5)
|
|
Register-ScheduledTask -TaskName "X9-WUDoneLock" -Action $lockAction -Trigger $lockTrigger `
|
|
-Principal $lockPrincipal -Settings $lockSettings -Force -ErrorAction SilentlyContinue | Out-Null
|
|
|
|
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
|