Files
oxmc d38cd32b82 Fix registry ownership/ACL and hang bugs in tiny11maker.ps1, plus build/setup script updates
Fixes several offline-hive build failures: TrustedInstaller-owned keys
(WindowsRuntime\ActivatableClassId, Explorer\Advanced, System\GameConfigStore, Search
SystemIndex) denying writes even to admin-owned processes, a PowerShell 5.1 quirk that drops
empty-string reg.exe arguments and can hang the build on a silent overwrite prompt, a
registry-handle leak that left hives locked and cascaded into DISM cleanup failures, and
relaxed the post-ResetBase health gate to accept 'Repairable' (only abort on
'NonRepairable') since ResetBase makes full repair impossible anyway - documented that
repairing the installed OS needs the original stock ISO, not the tweaked output. Also
rolls in in-progress updates to the other maker scripts and OEM setup/first-boot scripts.
2026-07-31 06:09:58 -07:00

132 lines
6.1 KiB
PowerShell

# Check PowerShell version for use in path
if ($PSVersionTable.PSVersion.Major -ge 3) {
# Use new variable syntax in PowerShell 3 and above
$currentDir = $PSScriptRoot
}
else {
# Use old variable syntax in Windows PowerShell 3 and below
$currentDir = (Get-Item .).FullName
}
# Import script-helper.ps1
. "$currentDir\..\..\scripts\script-helper.ps1"
$systemInfo = Get-SystemInfo
# Run BootCamp setup if AppsRoot is set and the installer exists
$appsRoot = [System.Environment]::GetEnvironmentVariable("AppsRoot", "Machine")
$bootcampPath = "$appsRoot\BootCamp\setup.exe"
if ($appsRoot -and (Test-Path $bootcampPath)) {
Write-Host "Running BootCamp setup..."
& $bootcampPath
}
#### Apply custom bootres.dll Secure Boot compatibility settings (only runs if flagged at build time) ####
& "$currentDir\enable-custom-bootres.ps1"
#### Install oxmc-servers Root Certificate (required for system apps) ####
Write-Output "Installing oxmc-servers root certificate..."
& "$windowsDrive\Windows\OEM\scripts\install-certs.ps1" -Silent
#### Add OEM apps bin folder to system PATH ####
$systemBinPath = "$windowsDrive\Windows\OEM\apps\system\bin"
try {
$machinePath = [Environment]::GetEnvironmentVariable("Path", "Machine")
if ($machinePath -notlike "*$systemBinPath*") {
$newMachinePath = "$machinePath;$systemBinPath"
[Environment]::SetEnvironmentVariable("Path", $newMachinePath, "Machine")
}
}
catch {
Write-Warning "Failed to update system PATH: $_"
}
#### Auto update packages task ####
schtasks /create /tn "DailyPackageUpdateoxmc" /tr "powershell.exe -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -File `"$windowsDrive\Windows\OEM\scripts\UpdatePackages-oxmc.ps1`"" /sc daily /st 06:00 /ru "SYSTEM" /rl HIGHEST /f
#### Register Windows Update Manager scheduled task ####
$wumScriptPath = "$windowsDrive\Windows\OEM\scripts\windowsupdate\WindowsUpdateManager.ps1"
$wumPrincipal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest -LogonType ServiceAccount
$wumSettings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries `
-StartWhenAvailable `
-RunOnlyIfNetworkAvailable `
-MultipleInstances IgnoreNew
# Scheduled check task — reads UpdateConfig.json at runtime to decide auto-install vs user picker
$wumAction = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$wumScriptPath`""
$wumTrigger1 = New-ScheduledTaskTrigger -Daily -At "6:00AM"
$wumTrigger2 = New-ScheduledTaskTrigger -Daily -At "6:00PM"
Unregister-ScheduledTask -TaskName "WindowsUpdateManager-AutoCheck" -Confirm:$false -ErrorAction SilentlyContinue
Register-ScheduledTask -TaskName "WindowsUpdateManager-AutoCheck" `
-Action $wumAction `
-Trigger @($wumTrigger1, $wumTrigger2) `
-Principal $wumPrincipal `
-Settings $wumSettings `
-Description "Checks for Windows updates; installs automatically or prompts user per config" | Out-Null
Write-Host "Windows Update Manager check task registered."
#### Register Windows Update Manager toast AUMID (machine-wide, all users) ####
$wumAumid = "oxmc-servers.WindowsUpdateManager"
$wumKey = "HKLM:\SOFTWARE\Classes\AppUserModelId\$wumAumid"
$null = New-Item -Path $wumKey -Force
Set-ItemProperty -Path $wumKey -Name "DisplayName" -Value "Windows Update Manager"
Set-ItemProperty -Path $wumKey -Name "ShowInSettings" -Value 1 -Type DWord
$wumIcon = "$windowsDrive\Windows\OEM\scripts\windowsupdate\wum-notify.png"
if (Test-Path $wumIcon) { Set-ItemProperty -Path $wumKey -Name "IconUri" -Value $wumIcon }
Write-Output "Windows Update Manager toast AUMID registered."
#### Disable inbox Windows Update scheduled tasks ####
# Prevents WU from running in the background alongside the custom manager.
# wuauserv stays on Manual (not Disabled) - the COM API used by WindowsUpdateManager.ps1 needs it.
Write-Host "Disabling inbox Windows Update scheduled tasks..."
$inboxWuTasks = @(
@{ Path = "\Microsoft\Windows\WindowsUpdate\"; Name = "Automatic App Update" },
@{ Path = "\Microsoft\Windows\WindowsUpdate\"; Name = "Scheduled Start" },
@{ Path = "\Microsoft\Windows\WindowsUpdate\"; Name = "sih" },
@{ Path = "\Microsoft\Windows\WindowsUpdate\"; Name = "sihboot" },
@{ Path = "\Microsoft\Windows\UpdateOrchestrator\"; Name = "Schedule Scan" },
@{ Path = "\Microsoft\Windows\UpdateOrchestrator\"; Name = "Schedule Scan Static Task" },
@{ Path = "\Microsoft\Windows\UpdateOrchestrator\"; Name = "UpdateModelTask" },
@{ Path = "\Microsoft\Windows\UpdateOrchestrator\"; Name = "USO_UxBroker" }
)
foreach ($t in $inboxWuTasks) {
Disable-ScheduledTask -TaskPath $t.Path -TaskName $t.Name -ErrorAction SilentlyContinue | Out-Null
}
Set-Service -Name wuauserv -StartupType Manual -ErrorAction SilentlyContinue
Write-Host "Inbox Windows Update tasks disabled. wuauserv set to Manual."
#### Install Runtime Libraries ####
# Install Visual C++ Redistributable packages
$runtimePath = "$windowsDrive\Windows\OEM\apps\runtime"
$vcredists = Get-ChildItem -Path $runtimePath -Filter "VC_redist*.exe" -ErrorAction SilentlyContinue
$installer = $null
if ($systemInfo.Architecture -in @("x64", "ARM64")) {
$installer = $vcredists | Where-Object { $_.Name -match "x64" } | Select-Object -First 1
}
if (-not $installer) {
$installer = $vcredists | Where-Object { $_.Name -match "x86" } | Select-Object -First 1
}
if ($installer) {
Write-Host "Installing Visual C++ Redistributable ($($installer.Name))..."
Start-Process -FilePath $installer.FullName `
-ArgumentList "/install", "/quiet", "/norestart" `
-Wait
}
else {
Write-Host "No Visual C++ Redistributable installer found."
}
# Get .NET Runtimes
$dotnetInstallers = Get-ChildItem -Path $runtimePath -Filter "*.exe" -ErrorAction SilentlyContinue
# Install runtimes
Install-DotNetPackage -Installers $dotnetInstallers -NamePattern "dotnet-runtime" -DisplayName ".NET Runtime"
Install-DotNetPackage -Installers $dotnetInstallers -NamePattern "windowsdesktop-runtime" -DisplayName "Windows Desktop Runtime"
# Run first-time-setup script
& "$currentDir\first-time-setup.ps1"