# 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"