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.
132 lines
6.1 KiB
PowerShell
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" |