From 94b7786aa83d68ef7ffc6bd63ff2c3eeaf9c6be1 Mon Sep 17 00:00:00 2001 From: X9 Dev Date: Fri, 29 May 2026 15:00:05 +0200 Subject: [PATCH] fix: field fixes from fresh Win11 deployment (Dell Latitude / GLBNTB63) - 02/11 winget: add --source winget to every install; fresh Win11 ISOs ship an App Installer with a stale pinned cert, so the msstore source fails with 0x8a15005e and aborts the install. Forcing the winget source bypasses msstore entirely. - 10 network: enable Network Discovery by -Group "@FirewallAPI.dll,-32752" (resource string) instead of -DisplayGroup "Network Discovery", which is localized and failed on Czech Windows. - 04 profile: set keyboard layout CZ primary + US secondary via Set-WinUserLanguageList (current user) and Preload in the Default hive and HKU\.DEFAULT (welcome screen / system accounts). Always applied. - 02 software: verify Atera via the AteraAgent service (Get-Service) with a path fallback incl. C:\ProgramData, since Atera no longer installs to a fixed location. - 12 windows-update: format Install-WindowsUpdate output via $_.Result/$_.Title instead of logging the raw object (was spamming "System.__ComObject"). Co-Authored-By: Claude Opus 4.8 --- scripts/02-software.ps1 | 28 ++++++++++++++++++----- scripts/04-default-profile.ps1 | 41 ++++++++++++++++++++++++++++++++++ scripts/10-network.ps1 | 7 ++++-- scripts/11-dell-update.ps1 | 4 ++++ scripts/12-windows-update.ps1 | 11 +++++++-- 5 files changed, 81 insertions(+), 10 deletions(-) diff --git a/scripts/02-software.ps1 b/scripts/02-software.ps1 index 6989b3f..4dd45d5 100644 --- a/scripts/02-software.ps1 +++ b/scripts/02-software.ps1 @@ -73,7 +73,12 @@ if (Get-Feature $Config "software" "wingetInstalls") { Write-Log " Starting: $($pkg.name) ($($pkg.wingetId))" -Level INFO $jobs += Start-Job -ArgumentList $pkg.wingetId, $pkg.name, $wingetExe -ScriptBlock { param($wingetId, $name, $wingetExe) + # --source winget forces the winget community repo and bypasses the + # msstore source, which fails on fresh Win11 ISOs whose App Installer + # ships a stale pinned cert (0x8a15005e: server certificate did not + # match any expected values), aborting the install. $output = & $wingetExe install --id $wingetId ` + --source winget ` --silent ` --accept-package-agreements ` --accept-source-agreements ` @@ -226,13 +231,24 @@ if (Get-Feature $Config "software" "ateraAgent") { Write-Log " Atera agent install exit code: $($msiProc.ExitCode)" -Level WARN } - # Verify binary exists - $ateraExe = "$env:ProgramFiles\ATERA Networks\AteraAgent\AteraAgent.exe" - $ateraExe86 = "${env:ProgramFiles(x86)}\ATERA Networks\AteraAgent\AteraAgent.exe" - if ((Test-Path $ateraExe) -or (Test-Path $ateraExe86)) { - Write-Log " Atera agent binary verified" -Level OK + # Verify install. The AteraAgent service is the most reliable signal - + # the agent registers it regardless of install path (Atera now sometimes + # lands under C:\ProgramData instead of Program Files). Fall back to the + # known binary locations if the service query is inconclusive. + $ateraSvc = Get-Service -Name "AteraAgent" -ErrorAction SilentlyContinue + if ($ateraSvc) { + Write-Log " Atera agent verified (service AteraAgent present, status $($ateraSvc.Status))" -Level OK } else { - Write-Log " Atera agent binary not found at expected paths" -Level WARN + $ateraPaths = @( + "$env:ProgramFiles\ATERA Networks\AteraAgent\AteraAgent.exe" + "${env:ProgramFiles(x86)}\ATERA Networks\AteraAgent\AteraAgent.exe" + "$env:ProgramData\ATERA Networks\AteraAgent\AteraAgent.exe" + ) + if ($ateraPaths | Where-Object { Test-Path $_ }) { + Write-Log " Atera agent binary verified" -Level OK + } else { + Write-Log " Atera agent service and binary not found at expected paths" -Level WARN + } } } catch { diff --git a/scripts/04-default-profile.ps1 b/scripts/04-default-profile.ps1 index 5b6d31e..6cf8ea2 100644 --- a/scripts/04-default-profile.ps1 +++ b/scripts/04-default-profile.ps1 @@ -344,6 +344,47 @@ $pinList -Name "WallpaperStyle" -Value "0" -Type "String" Set-ProfileReg -SubKey "Control Panel\Desktop" ` -Name "TileWallpaper" -Value "0" -Type "String" + + # =================================================================== + # KEYBOARD LAYOUTS - Czech primary, US secondary + # =================================================================== + # CZ stays the primary input language; US English is added as a harmless + # secondary so programmer/special chars are reachable. Applied in three + # places so every account type gets it: + # - current user (adminx9) via Set-WinUserLanguageList + # - Default profile hive -> every newly created user inherits it + # - HKU\.DEFAULT -> welcome screen and system/service accounts + # KLIDs: 00000405 = Czech, 00000409 = US English. + Write-Log "Configuring keyboard layouts (CZ primary, US secondary)" -Level STEP + + function Set-PreloadLayouts { + param([string]$KeyPath) # full Registry:: path to the "...\Keyboard Layout\Preload" key + try { + if (-not (Test-Path $KeyPath)) { New-Item -Path $KeyPath -Force -ErrorAction Stop | Out-Null } + Set-ItemProperty -Path $KeyPath -Name "1" -Value "00000405" -Type String -Force -ErrorAction Stop + Set-ItemProperty -Path $KeyPath -Name "2" -Value "00000409" -Type String -Force -ErrorAction Stop + Write-Log " Preload set (1=CZ, 2=US): $KeyPath" -Level OK + } + catch { + Write-Log " Failed to set Preload at $KeyPath - $_" -Level WARN + } + } + + # Current user: use the language-list API so the secondary layout shows up + # in the language bar, not just the raw Preload key. + try { + $langs = New-WinUserLanguageList -Language "cs-CZ" + $langs.Add("en-US") + Set-WinUserLanguageList -LanguageList $langs -Force -ErrorAction Stop + Write-Log " Current user language list set (cs-CZ + en-US)" -Level OK + } + catch { + Write-Log " Set-WinUserLanguageList failed - $_" -Level WARN + } + + # New users (Default profile hive) and welcome screen / system accounts (.DEFAULT) + Set-PreloadLayouts -KeyPath "Registry::HKU\DefaultProfile\Keyboard Layout\Preload" + Set-PreloadLayouts -KeyPath "Registry::HKU\.DEFAULT\Keyboard Layout\Preload" } finally { # ----------------------------------------------------------------------- diff --git a/scripts/10-network.ps1 b/scripts/10-network.ps1 index b0d2686..c9879da 100644 --- a/scripts/10-network.ps1 +++ b/scripts/10-network.ps1 @@ -85,8 +85,11 @@ catch { Write-Log "Enabling Network Discovery" -Level INFO try { - # Enable all Network Discovery rules for Private profile - Get-NetFirewallRule -DisplayGroup "Network Discovery" -ErrorAction Stop | + # Enable all Network Discovery rules for Private profile. + # Match by -Group resource string ("@FirewallAPI.dll,-32752") rather than + # -DisplayGroup: the display name is localized (e.g. "Zjistovani site" on + # Czech Win11), so DisplayGroup matching fails on non-English installs. + Get-NetFirewallRule -Group "@FirewallAPI.dll,-32752" -ErrorAction Stop | Where-Object { $_.Profile -match "Private|Any" } | Enable-NetFirewallRule -ErrorAction SilentlyContinue Write-Log " Network Discovery rules enabled (Private)" -Level OK diff --git a/scripts/11-dell-update.ps1 b/scripts/11-dell-update.ps1 index 0fb4493..e11f2d2 100644 --- a/scripts/11-dell-update.ps1 +++ b/scripts/11-dell-update.ps1 @@ -52,9 +52,13 @@ Write-Log "Dell confirmed: $model" -Level OK # ----------------------------------------------------------------------- Write-Log "Installing Dell Command | Update (Universal)..." -Level STEP +# --source winget forces the winget community repo and bypasses the msstore +# source, which fails on fresh Win11 ISOs whose App Installer ships a stale +# pinned cert (0x8a15005e), aborting the install. $wingetArgs = @( "install", "--id", "Dell.CommandUpdate.Universal", + "--source", "winget", "--silent", "--accept-package-agreements", "--accept-source-agreements" diff --git a/scripts/12-windows-update.ps1 b/scripts/12-windows-update.ps1 index c003285..080ca7f 100644 --- a/scripts/12-windows-update.ps1 +++ b/scripts/12-windows-update.ps1 @@ -65,8 +65,15 @@ if (-not $available -or @($available).Count -eq 0) { Write-Log " Found $($available.Count) update(s) - installing..." -Level INFO try { - $result = Install-WindowsUpdate -AcceptAll -IgnoreReboot -Verbose 2>&1 - $result | Where-Object { "$_" -match '\S' } | ForEach-Object { Write-Log " $_" -Level INFO } + # Format each update via its properties. Logging the raw object ($_) renders + # as "System.__ComObject" because the WUApiLib result objects have no useful + # ToString(); -Verbose 2>&1 also merged verbose-stream noise into the log. + $result = Install-WindowsUpdate -AcceptAll -IgnoreReboot + foreach ($u in $result) { + if ($u.Title) { + Write-Log (" {0} - {1}" -f $u.Result, $u.Title) -Level INFO + } + } Write-Log " Update pass complete - reboot required for next round" -Level OK } catch { Write-Log " Update install failed: $_" -Level ERROR