diff --git a/flash/Deploy-Windows.ps1 b/flash/Deploy-Windows.ps1
deleted file mode 100644
index 7b53b19..0000000
--- a/flash/Deploy-Windows.ps1
+++ /dev/null
@@ -1,244 +0,0 @@
-#Requires -RunAsAdministrator
-
-[CmdletBinding()]
-param(
- [switch]$SkipBloatware,
- [switch]$SkipSoftware,
- [switch]$SkipDefaultProfile,
- [switch]$DryRun
-)
-
-$ErrorActionPreference = "Continue"
-
-# -----------------------------------------------------------------------
-# Paths
-# -----------------------------------------------------------------------
-$ScriptRoot = $PSScriptRoot
-$LogDir = "C:\Windows\Setup\Scripts"
-$LogFile = "$LogDir\Deploy.log"
-$ConfigFile = "$ScriptRoot\config\config.json"
-
-# -----------------------------------------------------------------------
-# Logging
-# -----------------------------------------------------------------------
-function Write-Log {
- param(
- [string]$Message,
- [ValidateSet("INFO","OK","ERROR","WARN","STEP")]
- [string]$Level = "INFO"
- )
- $timestamp = Get-Date -Format "HH:mm:ss"
- $line = "[$timestamp] [$Level] $Message"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
- switch ($Level) {
- "OK" { Write-Host $line -ForegroundColor Green }
- "ERROR" { Write-Host $line -ForegroundColor Red }
- "WARN" { Write-Host $line -ForegroundColor Yellow }
- "STEP" { Write-Host $line -ForegroundColor Cyan }
- default { Write-Host $line }
- }
-}
-
-# -----------------------------------------------------------------------
-# Step runner - catches errors, logs, always continues
-# -----------------------------------------------------------------------
-$StepResults = [System.Collections.Generic.List[hashtable]]::new()
-
-function Invoke-Step {
- param(
- [string]$Name,
- [scriptblock]$Action
- )
-
- Write-Log "---- $Name ----" -Level STEP
-
- if ($DryRun) {
- Write-Log "DryRun - skipping execution" -Level WARN
- $StepResults.Add(@{ Name = $Name; Status = "DRYRUN" })
- return
- }
-
- try {
- & $Action
- Write-Log "$Name - OK" -Level OK
- $StepResults.Add(@{ Name = $Name; Status = "OK" })
- }
- catch {
- Write-Log "$Name - ERROR: $_" -Level ERROR
- $StepResults.Add(@{ Name = $Name; Status = "ERROR" })
- }
-}
-
-# -----------------------------------------------------------------------
-# Init
-# -----------------------------------------------------------------------
-if (-not (Test-Path $LogDir)) {
- New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
-}
-
-Write-Log "========================================" -Level INFO
-Write-Log "Deploy-Windows.ps1 started" -Level INFO
-Write-Log "Computer: $env:COMPUTERNAME" -Level INFO
-Write-Log "User: $env:USERNAME" -Level INFO
-Write-Log "Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -Level INFO
-if ($DryRun) { Write-Log "Mode: DRY RUN" -Level WARN }
-Write-Log "========================================" -Level INFO
-
-# -----------------------------------------------------------------------
-# Load config
-# -----------------------------------------------------------------------
-$Config = $null
-Invoke-Step -Name "Load config.json" -Action {
- if (-not (Test-Path $ConfigFile)) {
- throw "config.json not found: $ConfigFile"
- }
- $script:Config = Get-Content $ConfigFile -Raw -Encoding UTF8 | ConvertFrom-Json
- Write-Log "Config loaded from $ConfigFile" -Level INFO
-}
-
-# -----------------------------------------------------------------------
-# Build step enable/disable map from config + CLI overrides
-# -----------------------------------------------------------------------
-$stepsEnabled = @{
- adminAccount = $true
- bloatware = $true
- software = $true
- systemRegistry = $true
- defaultProfile = $true
- personalization = $true
- scheduledTasks = $true
- desktopInfo = $true
- activation = $true
-}
-if ($Config -and $Config.steps) {
- foreach ($key in @($stepsEnabled.Keys)) {
- $val = $Config.steps.$key
- if ($null -ne $val) { $stepsEnabled[$key] = [bool]$val }
- }
-}
-# CLI switches override config.steps
-if ($SkipBloatware) { $stepsEnabled['bloatware'] = $false }
-if ($SkipSoftware) { $stepsEnabled['software'] = $false }
-if ($SkipDefaultProfile) { $stepsEnabled['defaultProfile'] = $false }
-
-function Skip-Step {
- param([string]$Name)
- Write-Log "$Name - SKIPPED (disabled in config)" -Level WARN
- $StepResults.Add(@{ Name = $Name; Status = "SKIPPED" })
-}
-
-# -----------------------------------------------------------------------
-# Step 0a - Admin account
-# -----------------------------------------------------------------------
-if ($stepsEnabled['adminAccount']) {
- Invoke-Step -Name "Step 0a - Admin account" -Action {
- & "$ScriptRoot\scripts\00-admin-account.ps1" -Config $Config -LogFile $LogFile
- }
-} else { Skip-Step "Step 0a - Admin account" }
-
-# -----------------------------------------------------------------------
-# Step 0b - Windows activation
-# -----------------------------------------------------------------------
-if ($stepsEnabled['activation']) {
- Invoke-Step -Name "Step 0b - Windows activation" -Action {
- & "$ScriptRoot\scripts\08-activation.ps1" -Config $Config -LogFile $LogFile
- }
-} else { Skip-Step "Step 0b - Windows activation" }
-
-# -----------------------------------------------------------------------
-# Step 1 - Bloatware removal
-# -----------------------------------------------------------------------
-if ($stepsEnabled['bloatware']) {
- Invoke-Step -Name "Step 1 - Bloatware removal" -Action {
- & "$ScriptRoot\scripts\01-bloatware.ps1" -Config $Config -LogFile $LogFile
- }
-} else { Skip-Step "Step 1 - Bloatware removal" }
-
-# -----------------------------------------------------------------------
-# Step 2 - Software installation
-# -----------------------------------------------------------------------
-if ($stepsEnabled['software']) {
- Invoke-Step -Name "Step 2 - Software installation" -Action {
- & "$ScriptRoot\scripts\02-software.ps1" -Config $Config -LogFile $LogFile
- }
-} else { Skip-Step "Step 2 - Software installation" }
-
-# -----------------------------------------------------------------------
-# Step 3 - System registry (HKLM)
-# -----------------------------------------------------------------------
-if ($stepsEnabled['systemRegistry']) {
- Invoke-Step -Name "Step 3 - System registry" -Action {
- & "$ScriptRoot\scripts\03-system-registry.ps1" -Config $Config -LogFile $LogFile
- }
-} else { Skip-Step "Step 3 - System registry" }
-
-# -----------------------------------------------------------------------
-# Step 4 - Default profile (NTUSER.DAT)
-# -----------------------------------------------------------------------
-if ($stepsEnabled['defaultProfile']) {
- Invoke-Step -Name "Step 4 - Default profile" -Action {
- & "$ScriptRoot\scripts\04-default-profile.ps1" -Config $Config -LogFile $LogFile
- }
-} else { Skip-Step "Step 4 - Default profile" }
-
-# -----------------------------------------------------------------------
-# Step 5 - Personalization
-# -----------------------------------------------------------------------
-if ($stepsEnabled['personalization']) {
- Invoke-Step -Name "Step 5 - Personalization" -Action {
- & "$ScriptRoot\scripts\05-personalization.ps1" -Config $Config -LogFile $LogFile
- }
-} else { Skip-Step "Step 5 - Personalization" }
-
-# -----------------------------------------------------------------------
-# Step 6 - Scheduled tasks
-# -----------------------------------------------------------------------
-if ($stepsEnabled['scheduledTasks']) {
- Invoke-Step -Name "Step 6 - Scheduled tasks" -Action {
- & "$ScriptRoot\scripts\06-scheduled-tasks.ps1" -Config $Config -LogFile $LogFile
- }
-} else { Skip-Step "Step 6 - Scheduled tasks" }
-
-# -----------------------------------------------------------------------
-# Step 7 - DesktopInfo
-# -----------------------------------------------------------------------
-if ($stepsEnabled['desktopInfo']) {
- Invoke-Step -Name "Step 7 - DesktopInfo" -Action {
- & "$ScriptRoot\scripts\07-desktop-info.ps1" -Config $Config -LogFile $LogFile
- }
-} else { Skip-Step "Step 7 - DesktopInfo" }
-
-# -----------------------------------------------------------------------
-# Summary
-# -----------------------------------------------------------------------
-Write-Log "========================================" -Level INFO
-Write-Log "SUMMARY" -Level INFO
-Write-Log "========================================" -Level INFO
-
-$countOK = ($StepResults | Where-Object { $_.Status -eq "OK" }).Count
-$countError = ($StepResults | Where-Object { $_.Status -eq "ERROR" }).Count
-$countSkipped = ($StepResults | Where-Object { $_.Status -eq "SKIPPED" }).Count
-$countDryRun = ($StepResults | Where-Object { $_.Status -eq "DRYRUN" }).Count
-
-foreach ($r in $StepResults) {
- $lvl = switch ($r.Status) {
- "OK" { "OK" }
- "ERROR" { "ERROR" }
- "SKIPPED" { "WARN" }
- "DRYRUN" { "WARN" }
- }
- Write-Log "$($r.Status.PadRight(8)) $($r.Name)" -Level $lvl
-}
-
-Write-Log "----------------------------------------" -Level INFO
-Write-Log "OK: $countOK ERROR: $countError SKIPPED: $countSkipped DRYRUN: $countDryRun" -Level INFO
-Write-Log "Log saved to: $LogFile" -Level INFO
-Write-Log "========================================" -Level INFO
-
-if ($countError -gt 0) {
- Write-Log "Deployment finished with errors. Review log: $LogFile" -Level ERROR
- exit 1
-} else {
- Write-Log "Deployment finished successfully." -Level OK
- exit 0
-}
diff --git a/flash/Run.cmd b/flash/Run.cmd
deleted file mode 100644
index f7efc56..0000000
--- a/flash/Run.cmd
+++ /dev/null
@@ -1,125 +0,0 @@
-@echo off
-chcp 65001 >nul
-setlocal EnableDelayedExpansion
-
-:: -----------------------------------------------------------------------
-:: Auto-elevate to Administrator if not already elevated
-:: -----------------------------------------------------------------------
-net session >nul 2>&1
-if %errorlevel% neq 0 (
- echo Requesting administrator privileges...
- powershell -NoProfile -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
- exit /b
-)
-
-:: -----------------------------------------------------------------------
-:: Paths
-:: -----------------------------------------------------------------------
-set "SCRIPT_DIR=%~dp0"
-set "DEPLOY_PS1=%SCRIPT_DIR%Deploy-Windows.ps1"
-set "CONFIG_JSON=%SCRIPT_DIR%config\config.json"
-set "CONFIG_EDITOR=%SCRIPT_DIR%config-editor.hta"
-set "LOG_FILE=C:\Windows\Setup\Scripts\Deploy.log"
-
-:MENU
-cls
-echo.
-echo ================================================
-echo X9 - Windows Deployment
-echo ================================================
-echo.
-echo Config : %CONFIG_JSON%
-echo Log : %LOG_FILE%
-echo.
-echo [1] Full deployment (uses config.json)
-echo [2] Dry run (no changes, log only)
-echo [3] Skip bloatware removal
-echo [4] Skip software install
-echo [5] Open config editor (config-editor.hta)
-echo [0] Exit
-echo.
-set /p CHOICE=" Select [0-5]: "
-
-if "%CHOICE%"=="0" goto EXIT
-if "%CHOICE%"=="1" goto FULL
-if "%CHOICE%"=="2" goto DRYRUN
-if "%CHOICE%"=="3" goto SKIP_BLOATWARE
-if "%CHOICE%"=="4" goto SKIP_SOFTWARE
-if "%CHOICE%"=="5" goto OPEN_EDITOR
-
-echo Invalid choice. Try again.
-timeout /t 2 >nul
-goto MENU
-
-:: -----------------------------------------------------------------------
-:: [1] Full deployment
-:: -----------------------------------------------------------------------
-:FULL
-cls
-echo.
-echo Starting full deployment...
-echo.
-powershell -NoProfile -ExecutionPolicy Bypass -File "%DEPLOY_PS1%"
-goto DONE
-
-:: -----------------------------------------------------------------------
-:: [2] Dry run
-:: -----------------------------------------------------------------------
-:DRYRUN
-cls
-echo.
-echo Starting dry run (no changes will be made)...
-echo.
-powershell -NoProfile -ExecutionPolicy Bypass -File "%DEPLOY_PS1%" -DryRun
-goto DONE
-
-:: -----------------------------------------------------------------------
-:: [3] Skip bloatware
-:: -----------------------------------------------------------------------
-:SKIP_BLOATWARE
-cls
-echo.
-echo Starting deployment (bloatware removal skipped)...
-echo.
-powershell -NoProfile -ExecutionPolicy Bypass -File "%DEPLOY_PS1%" -SkipBloatware
-goto DONE
-
-:: -----------------------------------------------------------------------
-:: [4] Skip software
-:: -----------------------------------------------------------------------
-:SKIP_SOFTWARE
-cls
-echo.
-echo Starting deployment (software install skipped)...
-echo.
-powershell -NoProfile -ExecutionPolicy Bypass -File "%DEPLOY_PS1%" -SkipSoftware
-goto DONE
-
-:: -----------------------------------------------------------------------
-:: [5] Config editor
-:: -----------------------------------------------------------------------
-:OPEN_EDITOR
-if not exist "%CONFIG_EDITOR%" (
- echo ERROR: config-editor.hta not found: %CONFIG_EDITOR%
- pause
- goto MENU
-)
-start "" mshta.exe "%CONFIG_EDITOR%"
-goto MENU
-
-:: -----------------------------------------------------------------------
-:: Done
-:: -----------------------------------------------------------------------
-:DONE
-echo.
-echo ================================================
-echo Deployment finished.
-echo Log: %LOG_FILE%
-echo ================================================
-echo.
-pause
-goto MENU
-
-:EXIT
-endlocal
-exit /b 0
diff --git a/flash/config-editor.hta b/flash/config-editor.hta
deleted file mode 100644
index 168b558..0000000
--- a/flash/config-editor.hta
+++ /dev/null
@@ -1,632 +0,0 @@
-
-
-X9 - Deployment Config Editor
-
-
-
-
-
-
-
-
-
-
Steps
-
Software
-
Settings
-
-
-
-
-
-
-
-
-
- | On |
- Step |
- Name |
- |
-
-
-
-
-
-
-
-
-
-
-
-
- | Package Name |
- Winget ID |
- |
-
-
-
-
-
-
-
-
-
-
-
Deployment
-
-
Timezone
-
-
-
Locale
-
-
-
-
Admin Account
-
-
Username
-
-
-
Password
-
-
-
Description
-
-
-
-
PDF Default
-
-
Force Adobe Reader
-
-
-
Scheduled Task
-
-
-
-
Desktop Info
-
-
Enabled
-
-
-
Position
-
-
-
-
-
Font Size
-
-
-
Font Color
-
-
-
-
Activation
-
-
Product Key
-
-
-
KMS Server
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/flash/config/config.json b/flash/config/config.json
deleted file mode 100644
index 138c78b..0000000
--- a/flash/config/config.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "steps": {
- "adminAccount": true,
- "bloatware": true,
- "software": true,
- "systemRegistry": true,
- "defaultProfile": true,
- "personalization": true,
- "scheduledTasks": true,
- "desktopInfo": true,
- "activation": true
- },
- "deployment": {
- "timezone": "Central Europe Standard Time",
- "locale": "cs-CZ"
- },
- "adminAccount": {
- "username": "adminx9",
- "password": "AdminX9.AdminX9",
- "description": "X9 MSP admin account"
- },
- "activation": {
- "productKey": "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX",
- "kmsServer": ""
- },
- "software": {
- "install": [
- { "name": "7-Zip", "wingetId": "7zip.7zip" },
- { "name": "Adobe Acrobat Reader","wingetId": "Adobe.Acrobat.Reader.64-bit" },
- { "name": "OpenVPN Connect", "wingetId": "OpenVPNTechnologies.OpenVPNConnect" }
- ]
- },
- "bloatware": {
- "keepPackages": [
- "Microsoft.WindowsCalculator"
- ]
- },
- "desktopInfo": {
- "enabled": true,
- "position": "bottomRight",
- "fontSize": 12,
- "fontColor": "#FFFFFF",
- "backgroundColor": "transparent"
- },
- "pdfDefault": {
- "forceAdobeReader": true,
- "scheduledTaskEnabled": true
- }
-}
diff --git a/flash/jak_na_to.txt b/flash/jak_na_to.txt
deleted file mode 100644
index ef7edb2..0000000
--- a/flash/jak_na_to.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-X9 - Windows Deployment
-========================
-Automatizovana priprava noveho Windows 10/11 pocitace pro klienta.
-Spustit jednou jako Administrator na ciste nainstalovanem Windows.
-
-
-CO JE NA FLASHCE
-----------------
-Run.cmd - SPUSTIT TOTO. Hlavni spoustec s menu.
-config-editor.hta - Graficky editor konfigurace (dvojklik).
-Deploy-Windows.ps1 - Hlavni deployment skript (spousti Run.cmd).
-config\config.json - Konfigurace deploymentu.
-scripts\ - Jednotlive kroky deploymentu (00-08).
-
-
-JAK NA TO
----------
-1. Zapojit flashku do pocitace.
-
-2. Spustit Run.cmd pravym tlacitkem > "Spustit jako spravce".
- (nebo dvojklik - skript si sam vyziada adminova prava)
-
-3. Zobrazit se menu:
- [1] Full deployment - spusti vsechny kroky dle config.json
- [2] Dry run - projde vsechny kroky BEZ zmen, jen loguje
- [3] Skip bloatware - deployment bez odstranovani aplikaci
- [4] Skip software - deployment bez instalace softwaru
- [5] Open config editor - otevre graficky editor konfigurace
- [0] Exit
-
-4. Vybrat [1] pro standardni deployment.
-
-5. Po dokonceni zkontrolovat log:
- C:\Windows\Setup\Scripts\Deploy.log
-
-
-PRED DEPLOYMENTEM (volitelne)
-------------------------------
-Otevrit config-editor.hta (dvojklik) a zkontrolovat / upravit:
-
- Zalozka STEPS - zapnout / vypnout jednotlive kroky
- (kliknout na "i" pro popis co krok dela)
-
- Zalozka SOFTWARE - seznam aplikaci instalovanych pres winget
- (pridat / odebrat balicky)
-
- Zalozka SETTINGS - casova zona, nazev admin uctu,
- nastaveni DesktopInfo wallpaperu
-
-Po uprave kliknout "Save config.json". Zmeny se projeji pri
-spusteni deploymentu.
-
-
-CO DEPLOYMENT DELA (kroky v poradÃ)
--------------------------------------
-00 Admin account - vytvori lokalni admin ucet pro MSP pristup
-01 Bloatware - odebere nepotrebne aplikace (Teams, Xbox, ...)
-02 Software - nainstaluje aplikace pres winget
-03 System registry - HKLM tweaky (widgety, OneDrive, Edge, ...)
-04 Default profile - nastaveni taskbaru a Exploreru pro vsechny uzivatele
-05 Personalization - tmave tema, akcetni barva #223B47
-06 Scheduled tasks - registruje 4 ulohy (systray, PDF, DesktopInfo, ...)
-07 DesktopInfo - vlastni tapeta s info o pocitaci (jmeno, IP, OS, ...)
-08 Activation - aktivace Windows
-
-
-LOG
----
-Kazdy krok zapisuje do:
- C:\Windows\Setup\Scripts\Deploy.log
-
-Format zaznamu:
- [HH:mm:ss] [OK/ERROR/WARN] zprava
-
-Na konci logu je souhrn: pocet OK / ERROR / SKIPPED.
-
-
-POZNAMKY
---------
-- Skript vyzaduje pripojeni k internetu (winget instalace).
-- Restart pocitace neni potreba - spoustec na to upozorni pokud ano.
-- Nastaveni z Default Profile se aplikuji na KAZDEHO noveho uzivatele.
-- DesktopInfo tapeta se obnovi pri kazdem prihlaseni.
-- PDF default (Adobe Reader) se obnovuje pri kazdem prihlaseni jako ochrana
- proti tomu, ze Edge prepise asociaci.
-
-
-X9.cz MSP deployment suite
diff --git a/flash/scripts/00-admin-account.ps1 b/flash/scripts/00-admin-account.ps1
deleted file mode 100644
index bbd3390..0000000
--- a/flash/scripts/00-admin-account.ps1
+++ /dev/null
@@ -1,94 +0,0 @@
-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"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
-}
-
-# -----------------------------------------------------------------------
-# Read account config
-# -----------------------------------------------------------------------
-$accountName = "adminx9"
-$accountPass = "AdminX9.AdminX9"
-$accountDesc = "X9 MSP admin account"
-
-if ($Config -and $Config.adminAccount) {
- if ($Config.adminAccount.username) { $accountName = $Config.adminAccount.username }
- if ($Config.adminAccount.password) { $accountPass = $Config.adminAccount.password }
- if ($Config.adminAccount.description) { $accountDesc = $Config.adminAccount.description }
-}
-
-Write-Log "Creating admin account: $accountName" -Level INFO
-
-$securePass = ConvertTo-SecureString $accountPass -AsPlainText -Force
-
-# -----------------------------------------------------------------------
-# Create or update account
-# -----------------------------------------------------------------------
-$existing = Get-LocalUser -Name $accountName -ErrorAction SilentlyContinue
-
-if ($existing) {
- Write-Log " Account already exists - updating password" -Level INFO
- try {
- Set-LocalUser -Name $accountName -Password $securePass -PasswordNeverExpires $true
- Enable-LocalUser -Name $accountName
- Write-Log " Account updated: $accountName" -Level OK
- }
- catch {
- Write-Log " Failed to update account: $_" -Level ERROR
- }
-} else {
- try {
- New-LocalUser -Name $accountName `
- -Password $securePass `
- -Description $accountDesc `
- -PasswordNeverExpires `
- -UserMayNotChangePassword `
- -ErrorAction Stop | Out-Null
- Write-Log " Account created: $accountName" -Level OK
- }
- catch {
- Write-Log " Failed to create account: $_" -Level ERROR
- }
-}
-
-# -----------------------------------------------------------------------
-# Add to Administrators group
-# -----------------------------------------------------------------------
-try {
- $adminsGroup = (Get-LocalGroup | Where-Object { $_.SID -eq "S-1-5-32-544" }).Name
- $members = Get-LocalGroupMember -Group $adminsGroup -ErrorAction SilentlyContinue |
- Where-Object { $_.Name -like "*$accountName" }
- if (-not $members) {
- Add-LocalGroupMember -Group $adminsGroup -Member $accountName -ErrorAction Stop
- Write-Log " Added to $adminsGroup" -Level OK
- } else {
- Write-Log " Already in $adminsGroup" -Level INFO
- }
-}
-catch {
- Write-Log " Failed to add to Administrators: $_" -Level ERROR
-}
-
-# -----------------------------------------------------------------------
-# Hide account from login screen
-# -----------------------------------------------------------------------
-try {
- $specialPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList"
- if (-not (Test-Path $specialPath)) {
- New-Item -Path $specialPath -Force | Out-Null
- }
- Set-ItemProperty -Path $specialPath -Name $accountName -Value 0 -Type DWord -Force
- Write-Log " Account hidden from login screen" -Level OK
-}
-catch {
- Write-Log " Failed to hide account from login screen: $_" -Level ERROR
-}
-
-Write-Log "Step 0a - Admin account complete" -Level OK
diff --git a/flash/scripts/01-bloatware.ps1 b/flash/scripts/01-bloatware.ps1
deleted file mode 100644
index 30fbbe4..0000000
--- a/flash/scripts/01-bloatware.ps1
+++ /dev/null
@@ -1,184 +0,0 @@
-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"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
-}
-
-# -----------------------------------------------------------------------
-# 1a - AppX packages
-# -----------------------------------------------------------------------
-$AppxToRemove = @(
- "Microsoft.Microsoft3DViewer"
- "Microsoft.BingSearch"
- "Microsoft.WindowsCamera"
- "Clipchamp.Clipchamp"
- "Microsoft.WindowsAlarms"
- "Microsoft.Copilot"
- "Microsoft.549981C3F5F10"
- "Microsoft.Windows.DevHome"
- "MicrosoftCorporationII.MicrosoftFamily"
- "Microsoft.WindowsFeedbackHub"
- "Microsoft.Edge.GameAssist"
- "Microsoft.GetHelp"
- "Microsoft.Getstarted"
- "microsoft.windowscommunicationsapps"
- "Microsoft.WindowsMaps"
- "Microsoft.MixedReality.Portal"
- "Microsoft.BingNews"
- "Microsoft.MicrosoftOfficeHub"
- "Microsoft.Office.OneNote"
- "Microsoft.OutlookForWindows"
- "Microsoft.Paint"
- "Microsoft.MSPaint"
- "Microsoft.People"
- "Microsoft.Windows.Photos"
- "Microsoft.PowerAutomateDesktop"
- "MicrosoftCorporationII.QuickAssist"
- "Microsoft.SkypeApp"
- "Microsoft.ScreenSketch"
- "Microsoft.MicrosoftSolitaireCollection"
- "Microsoft.MicrosoftStickyNotes"
- "MicrosoftTeams"
- "MSTeams"
- "Microsoft.Todos"
- "Microsoft.WindowsSoundRecorder"
- "Microsoft.Wallet"
- "Microsoft.BingWeather"
- "Microsoft.WindowsTerminal"
- "Microsoft.Xbox.TCUI"
- "Microsoft.XboxApp"
- "Microsoft.XboxGameOverlay"
- "Microsoft.XboxGamingOverlay"
- "Microsoft.XboxIdentityProvider"
- "Microsoft.XboxSpeechToTextOverlay"
- "Microsoft.GamingApp"
- "Microsoft.YourPhone"
- "Microsoft.ZuneMusic"
- "Microsoft.ZuneVideo"
- "7EE7776C.LinkedInforWindows"
-)
-
-# Packages to always keep
-$KeepPackages = @("Microsoft.WindowsCalculator")
-if ($Config -and $Config.bloatware -and $Config.bloatware.keepPackages) {
- $KeepPackages += $Config.bloatware.keepPackages
-}
-$KeepPackages = $KeepPackages | Select-Object -Unique
-
-Write-Log "1a - Removing AppX packages" -Level STEP
-
-foreach ($pkg in $AppxToRemove) {
- if ($KeepPackages -contains $pkg) {
- Write-Log " KEEP $pkg" -Level INFO
- continue
- }
-
- # Installed packages (current user + all users)
- $installed = Get-AppxPackage -Name $pkg -AllUsers -ErrorAction SilentlyContinue
- if ($installed) {
- try {
- $installed | Remove-AppxPackage -AllUsers -ErrorAction Stop
- Write-Log " Removed AppxPackage: $pkg" -Level OK
- }
- catch {
- Write-Log " Failed to remove AppxPackage $pkg - $_" -Level WARN
- }
- }
-
- # Provisioned packages (for new users)
- $provisioned = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue |
- Where-Object { $_.DisplayName -eq $pkg }
- if ($provisioned) {
- try {
- $provisioned | Remove-AppxProvisionedPackage -Online -ErrorAction Stop | Out-Null
- Write-Log " Removed provisioned: $pkg" -Level OK
- }
- catch {
- Write-Log " Failed to remove provisioned $pkg - $_" -Level WARN
- }
- }
-
- if (-not $installed -and -not $provisioned) {
- Write-Log " Not found (already removed): $pkg" -Level INFO
- }
-}
-
-# -----------------------------------------------------------------------
-# 1b - Windows Capabilities
-# -----------------------------------------------------------------------
-$CapabilitiesToRemove = @(
- "Print.Fax.Scan"
- "Language.Handwriting"
- "Browser.InternetExplorer"
- "MathRecognizer"
- "OneCoreUAP.OneSync"
- "OpenSSH.Client"
- "Microsoft.Windows.MSPaint"
- "Microsoft.Windows.PowerShell.ISE"
- "App.Support.QuickAssist"
- "Microsoft.Windows.SnippingTool"
- "App.StepsRecorder"
- "Hello.Face"
- "Media.WindowsMediaPlayer"
- "Microsoft.Windows.WordPad"
-)
-
-Write-Log "1b - Removing Windows Capabilities" -Level STEP
-
-$installedCaps = Get-WindowsCapability -Online -ErrorAction SilentlyContinue
-
-foreach ($cap in $CapabilitiesToRemove) {
- # Match by prefix (e.g. Hello.Face matches Hello.Face.20134.0.0.0)
- $matches = $installedCaps | Where-Object {
- $_.Name -like "$cap*" -and $_.State -eq "Installed"
- }
- if ($matches) {
- foreach ($c in $matches) {
- try {
- Remove-WindowsCapability -Online -Name $c.Name -ErrorAction Stop | Out-Null
- Write-Log " Removed capability: $($c.Name)" -Level OK
- }
- catch {
- Write-Log " Failed to remove capability $($c.Name) - $_" -Level WARN
- }
- }
- } else {
- Write-Log " Not found or not installed: $cap" -Level INFO
- }
-}
-
-# -----------------------------------------------------------------------
-# 1c - Windows Optional Features
-# -----------------------------------------------------------------------
-$FeaturesToDisable = @(
- "MediaPlayback"
- "MicrosoftWindowsPowerShellV2Root"
- "Recall"
- "Microsoft-SnippingTool"
-)
-
-Write-Log "1c - Disabling Windows Optional Features" -Level STEP
-
-foreach ($feat in $FeaturesToDisable) {
- $feature = Get-WindowsOptionalFeature -Online -FeatureName $feat -ErrorAction SilentlyContinue
- if ($feature -and $feature.State -eq "Enabled") {
- try {
- Disable-WindowsOptionalFeature -Online -FeatureName $feat -NoRestart -ErrorAction Stop | Out-Null
- Write-Log " Disabled feature: $feat" -Level OK
- }
- catch {
- Write-Log " Failed to disable feature $feat - $_" -Level WARN
- }
- } else {
- Write-Log " Not enabled or not found: $feat" -Level INFO
- }
-}
-
-Write-Log "Step 1 complete" -Level OK
diff --git a/flash/scripts/02-software.ps1 b/flash/scripts/02-software.ps1
deleted file mode 100644
index f6d7cf1..0000000
--- a/flash/scripts/02-software.ps1
+++ /dev/null
@@ -1,122 +0,0 @@
-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"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
-}
-
-# -----------------------------------------------------------------------
-# Check winget availability
-# -----------------------------------------------------------------------
-Write-Log "Checking winget availability" -Level INFO
-
-$winget = Get-Command winget -ErrorAction SilentlyContinue
-if (-not $winget) {
- # Try to find winget in known locations
- $wingetPaths = @(
- "$env:LOCALAPPDATA\Microsoft\WindowsApps\winget.exe"
- "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller*\winget.exe"
- )
- foreach ($p in $wingetPaths) {
- $found = Get-Item $p -ErrorAction SilentlyContinue | Select-Object -First 1
- if ($found) { $winget = $found.FullName; break }
- }
-}
-
-if (-not $winget) {
- Write-Log "winget not found - software installation skipped" -Level ERROR
- exit 1
-}
-
-Write-Log "winget found: $($winget.Source -or $winget)" -Level OK
-
-# Accept agreements upfront
-& winget source update --accept-source-agreements 2>&1 | Out-Null
-
-# -----------------------------------------------------------------------
-# Install packages from config
-# -----------------------------------------------------------------------
-if (-not $Config -or -not $Config.software -or -not $Config.software.install) {
- Write-Log "No software list in config - skipping installs" -Level WARN
-} else {
- foreach ($pkg in $Config.software.install) {
- Write-Log "Installing $($pkg.name) ($($pkg.wingetId))" -Level INFO
- $result = & winget install --id $pkg.wingetId `
- --silent `
- --accept-package-agreements `
- --accept-source-agreements `
- --disable-interactivity `
- 2>&1
-
- $exitCode = $LASTEXITCODE
- if ($exitCode -eq 0) {
- Write-Log " Installed OK: $($pkg.name)" -Level OK
- } elseif ($exitCode -eq -1978335189) {
- # 0x8A150011 = already installed
- Write-Log " Already installed: $($pkg.name)" -Level OK
- } else {
- Write-Log " Failed: $($pkg.name) (exit $exitCode)" -Level ERROR
- Write-Log " Output: $($result -join ' ')" -Level ERROR
- }
- }
-}
-
-# -----------------------------------------------------------------------
-# Set Adobe Reader as default PDF app
-# -----------------------------------------------------------------------
-$forcePdf = $true
-if ($Config -and $Config.pdfDefault) {
- $forcePdf = [bool]$Config.pdfDefault.forceAdobeReader
-}
-
-if ($forcePdf) {
- Write-Log "Setting Adobe Reader as default PDF app" -Level INFO
-
- # Find Adobe PDF viewer executable (Acrobat DC or Reader DC)
- $acroPaths = @(
- "$env:ProgramFiles\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
- "${env:ProgramFiles(x86)}\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
- "${env:ProgramFiles(x86)}\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
- "$env:ProgramFiles\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
- "${env:ProgramFiles(x86)}\Adobe\Reader\Reader\AcroRd32.exe"
- )
- $acroExe = $acroPaths | Where-Object { Test-Path $_ } | Select-Object -First 1
-
- if (-not $acroExe) {
- Write-Log " Adobe PDF viewer not found - PDF default not set" -Level WARN
- } else {
- Write-Log " Found: $acroExe" -Level INFO
-
- # Set file type association via HKCR (system-wide, requires admin)
- $progId = "AcroExch.Document.DC"
- $openCmd = "`"$acroExe`" `"%1`""
-
- # HKCR\.pdf -> progId
- if (-not (Test-Path "HKCR:\.pdf")) {
- New-Item -Path "HKCR:\.pdf" -Force | Out-Null
- }
- Set-ItemProperty -Path "HKCR:\.pdf" -Name "(Default)" -Value $progId
-
- # HKCR\AcroExch.Document.DC\shell\open\command
- $cmdPath = "HKCR:\$progId\shell\open\command"
- if (-not (Test-Path $cmdPath)) {
- New-Item -Path $cmdPath -Force | Out-Null
- }
- Set-ItemProperty -Path $cmdPath -Name "(Default)" -Value $openCmd
-
- # Note: HKCU UserChoice requires a Windows-computed Hash value to be valid.
- # Direct ProgId write without Hash is silently reset by Windows on next access.
- # HKCR write above provides the system-wide default; per-user default is
- # handled by the PDF-DefaultApp scheduled task via HKCR on every logon.
-
- Write-Log " PDF default set to AcroRd32 (HKCR)" -Level OK
- }
-}
-
-Write-Log "Step 2 complete" -Level OK
diff --git a/flash/scripts/03-system-registry.ps1 b/flash/scripts/03-system-registry.ps1
deleted file mode 100644
index ac68be4..0000000
--- a/flash/scripts/03-system-registry.ps1
+++ /dev/null
@@ -1,322 +0,0 @@
-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"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
-}
-
-Add-Type -TypeDefinition @"
-using System;
-using System.Runtime.InteropServices;
-public class RegPrivilege {
- [DllImport("advapi32.dll", ExactSpelling=true, SetLastError=true)]
- static extern bool AdjustTokenPrivileges(IntPtr htok, bool disAll, ref TokPriv1Luid newState, int len, IntPtr prev, IntPtr relen);
- [DllImport("kernel32.dll", ExactSpelling=true)]
- static extern IntPtr GetCurrentProcess();
- [DllImport("advapi32.dll", ExactSpelling=true, SetLastError=true)]
- static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
- [DllImport("advapi32.dll", SetLastError=true)]
- static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- struct TokPriv1Luid { public int Count; public long Luid; public int Attr; }
- const int TOKEN_QUERY = 0x8;
- const int TOKEN_ADJUST = 0x20;
- const int SE_PRIVILEGE_ENABLED = 2;
- public static bool Enable(string privilege) {
- IntPtr htok = IntPtr.Zero;
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST | TOKEN_QUERY, ref htok)) return false;
- TokPriv1Luid tp; tp.Count = 1; tp.Luid = 0; tp.Attr = SE_PRIVILEGE_ENABLED;
- if (!LookupPrivilegeValue(null, privilege, ref tp.Luid)) return false;
- return AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
- }
-}
-"@ -ErrorAction SilentlyContinue
-
-function Grant-RegWriteAccess {
- param([string]$Path)
- # Grants Administrators FullControl on a TrustedInstaller-owned registry key.
- # Enables SeTakeOwnershipPrivilege + SeRestorePrivilege to override ACL.
- try {
- [RegPrivilege]::Enable("SeTakeOwnershipPrivilege") | Out-Null
- [RegPrivilege]::Enable("SeRestorePrivilege") | Out-Null
-
- $hive = $Path -replace '^(HKLM|HKCU|HKU|HKCR|HKCC):\\.*', '$1'
- $subkey = $Path -replace '^(HKLM|HKCU|HKU|HKCR|HKCC):\\', ''
- $rootKey = switch ($hive) {
- "HKLM" { [Microsoft.Win32.Registry]::LocalMachine }
- "HKCU" { [Microsoft.Win32.Registry]::CurrentUser }
- "HKCR" { [Microsoft.Win32.Registry]::ClassesRoot }
- }
-
- # Take ownership (requires SeTakeOwnershipPrivilege)
- $key = $rootKey.OpenSubKey($subkey,
- [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
- [System.Security.AccessControl.RegistryRights]::TakeOwnership)
- if ($key) {
- $acl = $key.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)
- $acl.SetOwner([System.Security.Principal.NTAccount]"BUILTIN\Administrators")
- $key.SetAccessControl($acl)
- $key.Close()
- }
-
- # Grant FullControl to Administrators (requires ChangePermissions)
- $key = $rootKey.OpenSubKey($subkey,
- [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
- [System.Security.AccessControl.RegistryRights]::ChangePermissions)
- if ($key) {
- $acl = $key.GetAccessControl()
- $rule = New-Object System.Security.AccessControl.RegistryAccessRule(
- "BUILTIN\Administrators",
- [System.Security.AccessControl.RegistryRights]::FullControl,
- [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit",
- [System.Security.AccessControl.PropagationFlags]::None,
- [System.Security.AccessControl.AccessControlType]::Allow)
- $acl.SetAccessRule($rule)
- $key.SetAccessControl($acl)
- $key.Close()
- }
- Write-Log " ACL fixed for $Path" -Level INFO
- }
- catch {
- Write-Log " Grant-RegWriteAccess failed for $Path - $_" -Level WARN
- }
-}
-
-function Set-Reg {
- param(
- [string]$Path,
- [string]$Name,
- $Value,
- [string]$Type = "DWord"
- )
- try {
- if (-not (Test-Path $Path)) {
- New-Item -Path $Path -Force -ErrorAction Stop | Out-Null
- }
- Set-ItemProperty -Path $Path -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop
- Write-Log " SET $Path\$Name = $Value" -Level OK
- }
- catch {
- # Retry 1: grant write access via ACL manipulation
- try {
- Grant-RegWriteAccess -Path $Path
- if (-not (Test-Path $Path)) {
- New-Item -Path $Path -Force -ErrorAction Stop | Out-Null
- }
- Set-ItemProperty -Path $Path -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop
- Write-Log " SET $Path\$Name = $Value (after ACL fix)" -Level OK
- return
- }
- catch { }
-
- # Retry 2: write via scheduled task running as SYSTEM
- # SYSTEM has full registry access regardless of key ACL
- try {
- $regType = switch ($Type) {
- "DWord" { "REG_DWORD" }
- "String" { "REG_SZ" }
- "ExpandString"{ "REG_EXPAND_SZ" }
- "MultiString" { "REG_MULTI_SZ" }
- "QWord" { "REG_QWORD" }
- default { "REG_DWORD" }
- }
- # Convert registry PS path to reg.exe path
- $regPath = $Path -replace '^HKLM:\\', 'HKLM\' `
- -replace '^HKCU:\\', 'HKCU\' `
- -replace '^HKCR:\\', 'HKCR\'
- $tempScript = "$env:TEMP\set-reg-system-$([System.IO.Path]::GetRandomFileName()).ps1"
- "reg add `"$regPath`" /v `"$Name`" /t $regType /d $Value /f" |
- Set-Content -Path $tempScript -Encoding UTF8
-
- $taskName = "TempRegFix-$([System.IO.Path]::GetRandomFileName())"
- $action = New-ScheduledTaskAction -Execute "cmd.exe" `
- -Argument "/c reg add `"$regPath`" /v `"$Name`" /t $regType /d $Value /f"
- $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest
- $settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Seconds 30)
- $task = New-ScheduledTask -Action $action -Principal $principal -Settings $settings
-
- Register-ScheduledTask -TaskName $taskName -InputObject $task -Force | Out-Null
- Start-ScheduledTask -TaskName $taskName
- Start-Sleep -Seconds 2
- Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
- Remove-Item $tempScript -Force -ErrorAction SilentlyContinue
-
- # Verify it was written
- $written = (Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue).$Name
- if ($null -ne $written) {
- Write-Log " SET $Path\$Name = $Value (via SYSTEM task)" -Level OK
- } else {
- Write-Log " FAILED $Path\$Name - SYSTEM task ran but value not found" -Level ERROR
- }
- }
- catch {
- Write-Log " FAILED $Path\$Name - $_" -Level ERROR
- }
- }
-}
-
-function Remove-Reg {
- param([string]$Path, [string]$Name)
- try {
- if (Test-Path $Path) {
- Remove-ItemProperty -Path $Path -Name $Name -Force -ErrorAction SilentlyContinue
- Write-Log " REMOVED $Path\$Name" -Level OK
- }
- }
- catch {
- Write-Log " FAILED removing $Path\$Name - $_" -Level ERROR
- }
-}
-
-Write-Log "3 - Applying HKLM system registry tweaks" -Level STEP
-
-# -----------------------------------------------------------------------
-# Bypass Network Requirement on OOBE (BypassNRO)
-# -----------------------------------------------------------------------
-Set-Reg -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" `
- -Name "BypassNRO" -Value 1
-
-# -----------------------------------------------------------------------
-# Disable auto-install of Teams (Chat)
-# -----------------------------------------------------------------------
-Set-Reg -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Communications" `
- -Name "ConfigureChatAutoInstall" -Value 0
-
-# -----------------------------------------------------------------------
-# Disable Cloud Optimized Content (ads in Start menu etc.)
-# -----------------------------------------------------------------------
-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" `
- -Name "DisableCloudOptimizedContent" -Value 1
-
-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" `
- -Name "DisableWindowsConsumerFeatures" -Value 1
-
-# -----------------------------------------------------------------------
-# Disable Widgets (News and Interests)
-# -----------------------------------------------------------------------
-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Dsh" `
- -Name "AllowNewsAndInterests" -Value 0
-
-# -----------------------------------------------------------------------
-# Microsoft Edge - hide First Run Experience
-# -----------------------------------------------------------------------
-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Edge" `
- -Name "HideFirstRunExperience" -Value 1
-
-# Also disable Edge desktop shortcut creation after install
-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\EdgeUpdate" `
- -Name "CreateDesktopShortcutDefault" -Value 0
-
-# -----------------------------------------------------------------------
-# Password - no expiration
-# -----------------------------------------------------------------------
-Write-Log " Setting password max age to UNLIMITED" -Level INFO
-$pwResult = & net accounts /maxpwage:UNLIMITED 2>&1
-if ($LASTEXITCODE -eq 0) {
- Write-Log " Password max age set to UNLIMITED" -Level OK
-} else {
- Write-Log " Failed to set password max age: $pwResult" -Level ERROR
-}
-
-# -----------------------------------------------------------------------
-# Time zone
-# -----------------------------------------------------------------------
-$tz = "Central Europe Standard Time"
-if ($Config -and $Config.deployment -and $Config.deployment.timezone) {
- $tz = $Config.deployment.timezone
-}
-Write-Log " Setting time zone: $tz" -Level INFO
-try {
- Set-TimeZone -Id $tz -ErrorAction Stop
- Write-Log " Time zone set: $tz" -Level OK
-}
-catch {
- Write-Log " Failed to set time zone: $_" -Level ERROR
-}
-
-# -----------------------------------------------------------------------
-# OneDrive - uninstall from clean Windows (no policy block)
-# NOTE: No policy key is set intentionally - M365 installation can reinstall
-# and run OneDrive normally. Policy DisableFileSyncNGSC would prevent that.
-# -----------------------------------------------------------------------
-Write-Log " Uninstalling OneDrive" -Level INFO
-
-# Remove OneDriveSetup.exe if present
-$oneDrivePaths = @(
- "$env:SystemRoot\System32\OneDriveSetup.exe"
- "$env:SystemRoot\SysWOW64\OneDriveSetup.exe"
-)
-foreach ($odPath in $oneDrivePaths) {
- if (Test-Path $odPath) {
- try {
- # Uninstall first
- & $odPath /uninstall 2>&1 | Out-Null
- Write-Log " OneDrive uninstalled via $odPath" -Level OK
- }
- catch {
- Write-Log " OneDrive uninstall failed: $_" -Level WARN
- }
- }
-}
-
-# Remove OneDrive Start Menu shortcut
-$odLnk = "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk"
-if (Test-Path $odLnk) {
- Remove-Item $odLnk -Force -ErrorAction SilentlyContinue
- Write-Log " Removed OneDrive Start Menu shortcut" -Level OK
-}
-
-# -----------------------------------------------------------------------
-# Outlook (new) - disable auto-install via UScheduler
-# -----------------------------------------------------------------------
-Write-Log " Disabling Outlook (new) auto-install" -Level INFO
-
-$uschedulerPaths = @(
- "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate"
- "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate"
-)
-foreach ($uPath in $uschedulerPaths) {
- if (Test-Path $uPath) {
- try {
- Remove-Item -Path $uPath -Recurse -Force
- Write-Log " Removed UScheduler key: $uPath" -Level OK
- }
- catch {
- Write-Log " Failed to remove UScheduler key: $_" -Level WARN
- }
- }
-}
-
-# -----------------------------------------------------------------------
-# Disable GameDVR
-# -----------------------------------------------------------------------
-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\GameDVR" `
- -Name "AllowGameDVR" -Value 0
-
-# -----------------------------------------------------------------------
-# Disable Recall (Windows AI feature)
-# -----------------------------------------------------------------------
-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" `
- -Name "DisableAIDataAnalysis" -Value 1
-
-# -----------------------------------------------------------------------
-# Search on taskbar - hide via HKLM policy (Win11 22H2+ enforcement)
-# User-level SearchboxTaskbarMode alone is insufficient on newer Win11 builds;
-# this policy key ensures the setting survives Windows Updates.
-# -----------------------------------------------------------------------
-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search" `
- -Name "SearchOnTaskbarMode" -Value 0
-
-# -----------------------------------------------------------------------
-# Start menu - hide Recommended section (Win11)
-# -----------------------------------------------------------------------
-Set-Reg -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" `
- -Name "HideRecommendedSection" -Value 1
-
-Write-Log "Step 3 complete" -Level OK
diff --git a/flash/scripts/04-default-profile.ps1 b/flash/scripts/04-default-profile.ps1
deleted file mode 100644
index 03b0b1e..0000000
--- a/flash/scripts/04-default-profile.ps1
+++ /dev/null
@@ -1,324 +0,0 @@
-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"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
-}
-
-# -----------------------------------------------------------------------
-# Helper - apply a registry setting to both Default hive and current HKCU
-# -----------------------------------------------------------------------
-function Grant-HiveWriteAccess {
- param([string]$HivePath) # full path e.g. "Registry::HKU\DefaultProfile\Software\..."
- # Grants Administrators FullControl on a loaded hive key with restricted ACL.
- try {
- $acl = Get-Acl -Path $HivePath -ErrorAction Stop
- $rule = New-Object System.Security.AccessControl.RegistryAccessRule(
- "BUILTIN\Administrators",
- [System.Security.AccessControl.RegistryRights]::FullControl,
- [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit",
- [System.Security.AccessControl.PropagationFlags]::None,
- [System.Security.AccessControl.AccessControlType]::Allow
- )
- $acl.SetAccessRule($rule)
- Set-Acl -Path $HivePath -AclObject $acl -ErrorAction Stop
- }
- catch {
- Write-Log " Grant-HiveWriteAccess failed for $HivePath - $_" -Level WARN
- }
-}
-
-function Set-ProfileReg {
- param(
- [string]$SubKey, # relative to HKCU (e.g. "Software\Microsoft\...")
- [string]$Name,
- $Value,
- [string]$Type = "DWord"
- )
-
- # Apply to loaded Default hive
- $defPath = "Registry::HKU\DefaultProfile\$SubKey"
- try {
- if (-not (Test-Path $defPath)) {
- New-Item -Path $defPath -Force -ErrorAction Stop | Out-Null
- }
- Set-ItemProperty -Path $defPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop
- }
- catch {
- # Retry after granting write access to parent key
- try {
- $parentPath = $defPath -replace '\\[^\\]+$', ''
- if (Test-Path $parentPath) { Grant-HiveWriteAccess -HivePath $parentPath }
- if (-not (Test-Path $defPath)) {
- New-Item -Path $defPath -Force -ErrorAction Stop | Out-Null
- }
- Set-ItemProperty -Path $defPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop
- }
- catch {
- Write-Log " DEFAULT HIVE failed $SubKey\$Name - $_" -Level ERROR
- }
- }
-
- # Apply to current user as well
- $hkcuPath = "HKCU:\$SubKey"
- try {
- if (-not (Test-Path $hkcuPath)) {
- New-Item -Path $hkcuPath -Force -ErrorAction Stop | Out-Null
- }
- Set-ItemProperty -Path $hkcuPath -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop
- Write-Log " SET $SubKey\$Name = $Value" -Level OK
- }
- catch {
- Write-Log " HKCU failed $SubKey\$Name - $_" -Level ERROR
- }
-}
-
-function Remove-ProfileReg {
- param([string]$SubKey, [string]$Name)
-
- $defPath = "Registry::HKU\DefaultProfile\$SubKey"
- try {
- if (Test-Path $defPath) {
- Remove-ItemProperty -Path $defPath -Name $Name -Force -ErrorAction SilentlyContinue
- }
- }
- catch { }
-
- $hkcuPath = "HKCU:\$SubKey"
- try {
- if (Test-Path $hkcuPath) {
- Remove-ItemProperty -Path $hkcuPath -Name $Name -Force -ErrorAction SilentlyContinue
- Write-Log " REMOVED $SubKey\$Name" -Level OK
- }
- }
- catch {
- Write-Log " FAILED removing $SubKey\$Name - $_" -Level ERROR
- }
-}
-
-# -----------------------------------------------------------------------
-# Load Default profile hive
-# -----------------------------------------------------------------------
-$hivePath = "C:\Users\Default\NTUSER.DAT"
-$hiveKey = "DefaultProfile"
-
-Write-Log "Loading Default hive: $hivePath" -Level INFO
-
-# Unload first in case previous run left it mounted
-& reg unload "HKU\$hiveKey" 2>&1 | Out-Null
-
-$loadResult = & reg load "HKU\$hiveKey" $hivePath 2>&1
-if ($LASTEXITCODE -ne 0) {
- Write-Log "Failed to load Default hive: $loadResult" -Level ERROR
- exit 1
-}
-Write-Log "Default hive loaded" -Level OK
-
-try {
- # -----------------------------------------------------------------------
- # Taskbar settings (Win10 + Win11)
- # -----------------------------------------------------------------------
- Write-Log "Applying taskbar settings" -Level STEP
-
- $tbPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
-
- # Win11: align taskbar to left (0 = left, 1 = center)
- Set-ProfileReg -SubKey $tbPath -Name "TaskbarAl" -Value 0
-
- # Hide Search box / button - Win10/11 (0 = hidden, 1 = icon, 2 = full box)
- # Note: Win11 uses Search subkey, Win10 uses Explorer\Advanced - set both
- Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Search" `
- -Name "SearchboxTaskbarMode" -Value 0
- Set-ProfileReg -SubKey $tbPath -Name "SearchboxTaskbarMode" -Value 0
-
- # Hide Task View button
- Set-ProfileReg -SubKey $tbPath -Name "ShowTaskViewButton" -Value 0
-
- # Hide Widgets button
- Set-ProfileReg -SubKey $tbPath -Name "TaskbarDa" -Value 0
-
- # Hide Chat / Teams button
- Set-ProfileReg -SubKey $tbPath -Name "TaskbarMn" -Value 0
-
- # Hide Copilot button
- Set-ProfileReg -SubKey $tbPath -Name "ShowCopilotButton" -Value 0
-
- # Show file extensions in Explorer
- Set-ProfileReg -SubKey $tbPath -Name "HideFileExt" -Value 0
-
- # Open Explorer to This PC instead of Quick Access
- Set-ProfileReg -SubKey $tbPath -Name "LaunchTo" -Value 1
-
- # -----------------------------------------------------------------------
- # System tray - show all icons
- # -----------------------------------------------------------------------
- # EnableAutoTray = 0 works on Win10; Win11 ignores it but set anyway
- Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer" `
- -Name "EnableAutoTray" -Value 0
-
- # Win11 workaround: clear cached tray icon streams so all icons appear on next login
- # Windows rebuilds the streams with all icons visible when no cache exists
- $trayNotifyKey = "HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify"
- if (Test-Path $trayNotifyKey) {
- Remove-ItemProperty -Path $trayNotifyKey -Name "IconStreams" -Force -ErrorAction SilentlyContinue
- Remove-ItemProperty -Path $trayNotifyKey -Name "PastIconsStream" -Force -ErrorAction SilentlyContinue
- Write-Log " Cleared TrayNotify icon streams (Win11 systray workaround)" -Level OK
- }
-
- # Also clear in Default hive so new users start with clean state
- $defTrayKey = "Registry::HKU\DefaultProfile\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify"
- if (Test-Path $defTrayKey) {
- Remove-ItemProperty -Path $defTrayKey -Name "IconStreams" -Force -ErrorAction SilentlyContinue
- Remove-ItemProperty -Path $defTrayKey -Name "PastIconsStream" -Force -ErrorAction SilentlyContinue
- Write-Log " Cleared TrayNotify icon streams in Default hive" -Level OK
- }
-
- # -----------------------------------------------------------------------
- # Desktop icons - show This PC
- # -----------------------------------------------------------------------
- # CLSID {20D04FE0-3AEA-1069-A2D8-08002B30309D} = This PC / Computer
- Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel" `
- -Name "{20D04FE0-3AEA-1069-A2D8-08002B30309D}" -Value 0
-
- # -----------------------------------------------------------------------
- # Start menu settings
- # -----------------------------------------------------------------------
- Write-Log "Applying Start menu settings" -Level STEP
-
- # Disable Bing search suggestions in Start menu
- Set-ProfileReg -SubKey "Software\Policies\Microsoft\Windows\Explorer" `
- -Name "DisableSearchBoxSuggestions" -Value 1
-
- # Win11: empty Start menu pins
- Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Start" `
- -Name "ConfigureStartPins" `
- -Value '{"pinnedList":[]}' `
- -Type "String"
-
- # Hide "Recently added" apps in Start menu
- Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" `
- -Name "Start_TrackProgs" -Value 0
-
- # Hide recently opened files/docs from Start menu
- Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" `
- -Name "Start_TrackDocs" -Value 0
-
- # -----------------------------------------------------------------------
- # Copilot - disable
- # -----------------------------------------------------------------------
- Set-ProfileReg -SubKey "Software\Policies\Microsoft\Windows\WindowsCopilot" `
- -Name "TurnOffWindowsCopilot" -Value 1
-
- # -----------------------------------------------------------------------
- # GameDVR - disable
- # -----------------------------------------------------------------------
- Set-ProfileReg -SubKey "System\GameConfigStore" `
- -Name "GameDVR_Enabled" -Value 0
-
- Set-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\GameDVR" `
- -Name "AppCaptureEnabled" -Value 0
-
- # -----------------------------------------------------------------------
- # Num Lock on startup
- # -----------------------------------------------------------------------
- Set-ProfileReg -SubKey "Control Panel\Keyboard" `
- -Name "InitialKeyboardIndicators" -Value 2 -Type "String"
-
- # -----------------------------------------------------------------------
- # Accent color on title bars
- # -----------------------------------------------------------------------
- Set-ProfileReg -SubKey "Software\Microsoft\Windows\DWM" `
- -Name "ColorPrevalence" -Value 1
-
- # -----------------------------------------------------------------------
- # OneDrive - remove RunOnce key from Default profile
- # -----------------------------------------------------------------------
- Write-Log "Removing OneDrive from Default profile RunOnce" -Level INFO
- Remove-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\Run" `
- -Name "OneDriveSetup"
-
- Remove-ProfileReg -SubKey "Software\Microsoft\Windows\CurrentVersion\RunOnce" `
- -Name "Delete Cached Standalone Update Binary"
-
- # Remove OneDrive from Explorer namespace (left panel)
- $oneDriveClsid = "{018D5C66-4533-4307-9B53-224DE2ED1FE6}"
- $nsPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\$oneDriveClsid"
- $defNsPath = "Registry::HKU\DefaultProfile\$nsPath"
- if (Test-Path $defNsPath) {
- Remove-Item -Path $defNsPath -Recurse -Force -ErrorAction SilentlyContinue
- Write-Log " Removed OneDrive from Explorer namespace (Default)" -Level OK
- }
- $hkcuNsPath = "HKCU:\$nsPath"
- if (Test-Path $hkcuNsPath) {
- Remove-Item -Path $hkcuNsPath -Recurse -Force -ErrorAction SilentlyContinue
- Write-Log " Removed OneDrive from Explorer namespace (HKCU)" -Level OK
- }
-
- # -----------------------------------------------------------------------
- # Empty taskbar pinned apps (Win10/11)
- # -----------------------------------------------------------------------
- Write-Log "Clearing taskbar pinned apps layout" -Level INFO
-
- $taskbarLayoutDir = "C:\Users\Default\AppData\Local\Microsoft\Windows\Shell"
- if (-not (Test-Path $taskbarLayoutDir)) {
- New-Item -ItemType Directory -Path $taskbarLayoutDir -Force | Out-Null
- }
-
- $taskbarLayoutXml = @"
-
-
-
-
-
-
-
-
-
-"@
- $taskbarLayoutXml | Set-Content -Path "$taskbarLayoutDir\LayoutModification.xml" -Encoding UTF8 -Force
- Write-Log " Taskbar LayoutModification.xml written" -Level OK
-
-}
-finally {
- # -----------------------------------------------------------------------
- # Unload Default hive - always, even on error
- # -----------------------------------------------------------------------
- Write-Log "Unloading Default hive" -Level INFO
- [GC]::Collect()
- [GC]::WaitForPendingFinalizers()
- Start-Sleep -Milliseconds 500
-
- $unloadResult = & reg unload "HKU\$hiveKey" 2>&1
- if ($LASTEXITCODE -eq 0) {
- Write-Log "Default hive unloaded" -Level OK
- } else {
- Write-Log "Failed to unload Default hive: $unloadResult" -Level ERROR
- }
-}
-
-# -----------------------------------------------------------------------
-# Restart Explorer to apply taskbar/tray changes to current session
-# -----------------------------------------------------------------------
-Write-Log "Restarting Explorer to apply taskbar changes" -Level INFO
-try {
- Stop-Process -Name explorer -Force -ErrorAction SilentlyContinue
- Start-Sleep -Seconds 2
- Start-Process explorer
- Write-Log "Explorer restarted" -Level OK
-}
-catch {
- Write-Log "Explorer restart failed (non-fatal): $_" -Level WARN
-}
-
-Write-Log "Step 4 complete" -Level OK
diff --git a/flash/scripts/05-personalization.ps1 b/flash/scripts/05-personalization.ps1
deleted file mode 100644
index 957806e..0000000
--- a/flash/scripts/05-personalization.ps1
+++ /dev/null
@@ -1,172 +0,0 @@
-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"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
-}
-
-# Accent color #223B47 stored as ABGR DWORD: 0xFF473B22
-# A=FF B=47 G=3B R=22 -> 0xFF473B22 = 4283612962
-$AccentColorABGR = 0xFF473B22
-
-# Gradient colors (Windows generates these automatically but we set them explicitly)
-# AccentPalette is 32 bytes - 8 shades of the accent color (BGRA each)
-# We use the same color for all shades as a safe default
-$AccentColorHex = "#223B47"
-
-function Set-Reg {
- param([string]$Path, [string]$Name, $Value, [string]$Type = "DWord")
- try {
- if (-not (Test-Path $Path)) { New-Item -Path $Path -Force | Out-Null }
- Set-ItemProperty -Path $Path -Name $Name -Value $Value -Type $Type -Force
- Write-Log " SET $Path\$Name = $Value" -Level OK
- }
- catch {
- Write-Log " FAILED $Path\$Name - $_" -Level ERROR
- }
-}
-
-function Apply-ThemeSettings {
- param([string]$HiveRoot) # "HKCU:" or "Registry::HKU\DefaultProfile"
-
- # -----------------------------------------------------------------------
- # System theme - Dark (taskbar, Start, action center)
- # -----------------------------------------------------------------------
- Set-Reg -Path "$HiveRoot\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" `
- -Name "SystemUsesLightTheme" -Value 0
-
- # -----------------------------------------------------------------------
- # App theme - Light
- # -----------------------------------------------------------------------
- Set-Reg -Path "$HiveRoot\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" `
- -Name "AppsUseLightTheme" -Value 1
-
- # -----------------------------------------------------------------------
- # Accent color on Start and taskbar
- # -----------------------------------------------------------------------
- Set-Reg -Path "$HiveRoot\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" `
- -Name "ColorPrevalence" -Value 1
-
- # -----------------------------------------------------------------------
- # Transparency effects - disabled
- # -----------------------------------------------------------------------
- Set-Reg -Path "$HiveRoot\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" `
- -Name "EnableTransparency" -Value 0
-
- # -----------------------------------------------------------------------
- # Accent color
- # -----------------------------------------------------------------------
- Set-Reg -Path "$HiveRoot\Software\Microsoft\Windows\DWM" `
- -Name "AccentColor" -Value $AccentColorABGR -Type "DWord"
-
- Set-Reg -Path "$HiveRoot\Software\Microsoft\Windows\DWM" `
- -Name "ColorizationColor" -Value $AccentColorABGR -Type "DWord"
-
- Set-Reg -Path "$HiveRoot\Software\Microsoft\Windows\DWM" `
- -Name "ColorizationAfterglow" -Value $AccentColorABGR -Type "DWord"
-
- # Accent color on title bars and borders
- Set-Reg -Path "$HiveRoot\Software\Microsoft\Windows\DWM" `
- -Name "ColorPrevalence" -Value 1
-
- # -----------------------------------------------------------------------
- # Wallpaper - solid color #223B47 (fallback before DesktopInfo runs)
- # -----------------------------------------------------------------------
- # Background color as decimal RGB
- Set-Reg -Path "$HiveRoot\Control Panel\Colors" `
- -Name "Background" -Value "34 59 71" -Type "String"
-
- Set-Reg -Path "$HiveRoot\Control Panel\Desktop" `
- -Name "WallpaperStyle" -Value "0" -Type "String"
-
- Set-Reg -Path "$HiveRoot\Control Panel\Desktop" `
- -Name "TileWallpaper" -Value "0" -Type "String"
-
- # -----------------------------------------------------------------------
- # Desktop icons - show This PC
- # -----------------------------------------------------------------------
- Set-Reg -Path "$HiveRoot\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel" `
- -Name "{20D04FE0-3AEA-1069-A2D8-08002B30309D}" -Value 0
-}
-
-# -----------------------------------------------------------------------
-# Load Default hive
-# -----------------------------------------------------------------------
-$hivePath = "C:\Users\Default\NTUSER.DAT"
-$hiveKey = "DefaultProfile"
-
-Write-Log "Loading Default hive for personalization" -Level INFO
-
-& reg unload "HKU\$hiveKey" 2>&1 | Out-Null
-$loadResult = & reg load "HKU\$hiveKey" $hivePath 2>&1
-if ($LASTEXITCODE -ne 0) {
- Write-Log "Failed to load Default hive: $loadResult" -Level ERROR
- Write-Log "Applying personalization to current user only" -Level WARN
-
- Write-Log "Applying theme to current user (HKCU)" -Level STEP
- Apply-ThemeSettings -HiveRoot "HKCU:"
-
- # Set wallpaper via SystemParametersInfo for current user
- Add-Type -TypeDefinition @"
-using System;
-using System.Runtime.InteropServices;
-public class WallpaperHelper {
- [DllImport("user32.dll", CharSet=CharSet.Auto)]
- public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
-}
-"@ -ErrorAction SilentlyContinue
- [WallpaperHelper]::SystemParametersInfo(20, 0, "", 3) | Out-Null
- exit 0
-}
-
-try {
- Write-Log "Applying theme to Default hive" -Level STEP
- Apply-ThemeSettings -HiveRoot "Registry::HKU\DefaultProfile"
-
- Write-Log "Applying theme to current user (HKCU)" -Level STEP
- Apply-ThemeSettings -HiveRoot "HKCU:"
-}
-finally {
- [GC]::Collect()
- [GC]::WaitForPendingFinalizers()
- Start-Sleep -Milliseconds 500
-
- $unloadResult = & reg unload "HKU\$hiveKey" 2>&1
- if ($LASTEXITCODE -eq 0) {
- Write-Log "Default hive unloaded" -Level OK
- } else {
- Write-Log "Failed to unload Default hive: $unloadResult" -Level ERROR
- }
-}
-
-# -----------------------------------------------------------------------
-# Apply wallpaper (solid color) to current desktop session
-# -----------------------------------------------------------------------
-Write-Log "Setting desktop wallpaper to solid color" -Level INFO
-
-try {
- Add-Type -TypeDefinition @"
-using System;
-using System.Runtime.InteropServices;
-public class WallpaperHelper {
- [DllImport("user32.dll", CharSet=CharSet.Auto)]
- public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
-}
-"@ -ErrorAction SilentlyContinue
-
- # SPI_SETDESKTOPWALLPAPER=20, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE=3
- # Empty string = solid color defined in Control Panel\Colors\Background
- [WallpaperHelper]::SystemParametersInfo(20, 0, "", 3) | Out-Null
- Write-Log " Desktop wallpaper updated" -Level OK
-}
-catch {
- Write-Log " Failed to update wallpaper: $_" -Level WARN
-}
-
-Write-Log "Step 5 complete" -Level OK
diff --git a/flash/scripts/06-scheduled-tasks.ps1 b/flash/scripts/06-scheduled-tasks.ps1
deleted file mode 100644
index fbdfec8..0000000
--- a/flash/scripts/06-scheduled-tasks.ps1
+++ /dev/null
@@ -1,194 +0,0 @@
-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"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
-}
-
-$ScriptDir = "C:\Windows\Setup\Scripts"
-if (-not (Test-Path $ScriptDir)) {
- New-Item -ItemType Directory -Path $ScriptDir -Force | Out-Null
-}
-
-function Register-Task {
- param(
- [string]$TaskName,
- [string]$Description,
- [object]$Action,
- [object[]]$Triggers,
- [string]$RunLevel = "Highest"
- )
- try {
- # Remove existing task with same name
- Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
-
- $settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 5) `
- -MultipleInstances IgnoreNew `
- -StartWhenAvailable
-
- $principal = New-ScheduledTaskPrincipal -GroupId "Users" `
- -RunLevel $RunLevel
-
- $task = New-ScheduledTask -Action $Action `
- -Trigger $Triggers `
- -Settings $settings `
- -Principal $principal `
- -Description $Description
-
- Register-ScheduledTask -TaskName $TaskName -InputObject $task -Force | Out-Null
- Write-Log " Registered task: $TaskName" -Level OK
- }
- catch {
- Write-Log " Failed to register task $TaskName - $_" -Level ERROR
- }
-}
-
-# -----------------------------------------------------------------------
-# Task: ShowAllTrayIcons
-# Runs on logon: clears TrayNotify icon cache and restarts Explorer so all
-# tray icons are visible on first login (Win10: EnableAutoTray=0, Win11: cache clear)
-# -----------------------------------------------------------------------
-Write-Log "Registering task: ShowAllTrayIcons" -Level STEP
-
-$showTrayScript = "$ScriptDir\ShowAllTrayIcons.ps1"
-@'
-# Win10: disable auto-hiding of tray icons
-$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer"
-Set-ItemProperty -Path $regPath -Name "EnableAutoTray" -Value 0 -Force -ErrorAction SilentlyContinue
-
-# Win11: clear icon stream cache so all icons become visible after Explorer restart
-$trayPath = "HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify"
-if (Test-Path $trayPath) {
- Remove-ItemProperty -Path $trayPath -Name "IconStreams" -Force -ErrorAction SilentlyContinue
- Remove-ItemProperty -Path $trayPath -Name "PastIconsStream" -Force -ErrorAction SilentlyContinue
-}
-
-# Restart Explorer to apply changes
-Stop-Process -Name explorer -Force -ErrorAction SilentlyContinue
-Start-Sleep -Milliseconds 1500
-if (-not (Get-Process explorer -ErrorAction SilentlyContinue)) {
- Start-Process explorer
-}
-'@ | Set-Content -Path $showTrayScript -Encoding UTF8 -Force
-
-$showTrayAction = New-ScheduledTaskAction -Execute "powershell.exe" `
- -Argument "-NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$showTrayScript`""
-$showTrayTrigger = New-ScheduledTaskTrigger -AtLogOn
-
-Register-Task -TaskName "ShowAllTrayIcons" `
- -Description "Show all system tray icons for current user" `
- -Action $showTrayAction `
- -Triggers $showTrayTrigger
-
-# -----------------------------------------------------------------------
-# Task: PDF-DefaultApp
-# Runs on every logon, restores .pdf -> Adobe Reader association
-# Guards against Edge overwriting it
-# -----------------------------------------------------------------------
-Write-Log "Registering task: PDF-DefaultApp" -Level STEP
-
-$pdfScript = "$ScriptDir\PDF-DefaultApp.ps1"
-@'
-# Restore .pdf -> Adobe Reader HKCR association (system-wide).
-# Runs as SYSTEM so it can write to HKCR regardless of Edge updates.
-# Note: HKCU UserChoice requires Windows Hash validation and cannot be
-# set reliably via registry; HKCR provides the system-wide fallback.
-$acroPaths = @(
- "$env:ProgramFiles\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
- "${env:ProgramFiles(x86)}\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
- "${env:ProgramFiles(x86)}\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
- "$env:ProgramFiles\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
- "${env:ProgramFiles(x86)}\Adobe\Reader\Reader\AcroRd32.exe"
-)
-$acroExe = $acroPaths | Where-Object { Test-Path $_ } | Select-Object -First 1
-if (-not $acroExe) { exit 0 }
-
-$progId = "AcroExch.Document.DC"
-$openCmd = "`"$acroExe`" `"%1`""
-
-# HKCR\.pdf
-if (-not (Test-Path "HKCR:\.pdf")) { New-Item -Path "HKCR:\.pdf" -Force | Out-Null }
-$current = (Get-ItemProperty -Path "HKCR:\.pdf" -Name "(Default)" -ErrorAction SilentlyContinue)."(Default)"
-if ($current -ne $progId) {
- Set-ItemProperty -Path "HKCR:\.pdf" -Name "(Default)" -Value $progId -Force
-}
-
-# HKCR\AcroExch.Document.DC\shell\open\command
-$cmdPath = "HKCR:\$progId\shell\open\command"
-if (-not (Test-Path $cmdPath)) { New-Item -Path $cmdPath -Force | Out-Null }
-Set-ItemProperty -Path $cmdPath -Name "(Default)" -Value $openCmd -Force
-'@ | Set-Content -Path $pdfScript -Encoding UTF8 -Force
-
-$pdfAction = New-ScheduledTaskAction -Execute "powershell.exe" `
- -Argument "-NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$pdfScript`""
-$pdfTrigger = New-ScheduledTaskTrigger -AtLogOn
-
-# Runs as SYSTEM to allow HKCR writes (system-wide file association)
-$pdfPrincipal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest
-$pdfSettings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 2) `
- -MultipleInstances IgnoreNew `
- -StartWhenAvailable
-$pdfTask = New-ScheduledTask -Action $pdfAction `
- -Trigger $pdfTrigger `
- -Settings $pdfSettings `
- -Principal $pdfPrincipal `
- -Description "Restore Adobe Reader as default PDF app on logon"
-try {
- Unregister-ScheduledTask -TaskName "PDF-DefaultApp" -Confirm:$false -ErrorAction SilentlyContinue
- Register-ScheduledTask -TaskName "PDF-DefaultApp" -InputObject $pdfTask -Force | Out-Null
- Write-Log " Registered task: PDF-DefaultApp" -Level OK
-}
-catch {
- Write-Log " Failed to register task PDF-DefaultApp - $_" -Level ERROR
-}
-
-# -----------------------------------------------------------------------
-# Task: UnlockStartLayout
-# Runs once after deployment to unlock the Start menu layout
-# so users can still customize it later
-# -----------------------------------------------------------------------
-Write-Log "Registering task: UnlockStartLayout" -Level STEP
-
-$unlockScript = "$ScriptDir\UnlockStartLayout.ps1"
-@'
-# Remove Start layout lock so users can modify it
-$layoutXml = "C:\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml"
-if (Test-Path $layoutXml) {
- Remove-Item $layoutXml -Force -ErrorAction SilentlyContinue
-}
-
-# Unregister self after running once
-Unregister-ScheduledTask -TaskName "UnlockStartLayout" -Confirm:$false -ErrorAction SilentlyContinue
-'@ | Set-Content -Path $unlockScript -Encoding UTF8 -Force
-
-$unlockAction = New-ScheduledTaskAction -Execute "powershell.exe" `
- -Argument "-NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$unlockScript`""
-# Trigger: 5 minutes after system startup, once
-$unlockTrigger = New-ScheduledTaskTrigger -AtStartup
-$unlockTrigger.Delay = "PT5M"
-
-$unlockPrincipal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest
-$unlockSettings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 10) `
- -StartWhenAvailable
-$unlockTask = New-ScheduledTask -Action $unlockAction `
- -Trigger $unlockTrigger `
- -Settings $unlockSettings `
- -Principal $unlockPrincipal `
- -Description "Unlock Start menu layout 5 min after first boot"
-
-try {
- Unregister-ScheduledTask -TaskName "UnlockStartLayout" -Confirm:$false -ErrorAction SilentlyContinue
- Register-ScheduledTask -TaskName "UnlockStartLayout" -InputObject $unlockTask -Force | Out-Null
- Write-Log " Registered task: UnlockStartLayout" -Level OK
-}
-catch {
- Write-Log " Failed to register task UnlockStartLayout - $_" -Level ERROR
-}
-
-Write-Log "Step 6 complete" -Level OK
diff --git a/flash/scripts/07-desktop-info.ps1 b/flash/scripts/07-desktop-info.ps1
deleted file mode 100644
index 84f2e7f..0000000
--- a/flash/scripts/07-desktop-info.ps1
+++ /dev/null
@@ -1,235 +0,0 @@
-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"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
-}
-
-$ScriptDir = "C:\Windows\Setup\Scripts"
-$RenderScript = "$ScriptDir\DesktopInfo-Render.ps1"
-$BmpPath = "$ScriptDir\desktopinfo.bmp"
-
-if (-not (Test-Path $ScriptDir)) {
- New-Item -ItemType Directory -Path $ScriptDir -Force | Out-Null
-}
-
-# -----------------------------------------------------------------------
-# Write the rendering script (runs on every logon as the user)
-# Layout: hostname (large bold, centered), then detail lines centered
-# -----------------------------------------------------------------------
-Write-Log "Writing DesktopInfo render script to $RenderScript" -Level INFO
-
-$renderContent = @'
-# DesktopInfo-Render.ps1
-# Collects system info and renders it centered on the desktop wallpaper.
-# Runs on every user logon via Scheduled Task.
-
-$ErrorActionPreference = "Continue"
-$LogFile = "C:\Windows\Setup\Scripts\desktopinfo.log"
-function Write-Log {
- param([string]$Message, [string]$Level = "INFO")
- Add-Content -Path $LogFile -Value "[$(Get-Date -Format 'HH:mm:ss')] [$Level] $Message" -Encoding UTF8
-}
-Write-Log "DesktopInfo render started" -Level INFO
-
-Add-Type -AssemblyName System.Drawing
-Add-Type -AssemblyName System.Windows.Forms
-Add-Type -TypeDefinition @"
-using System;
-using System.Runtime.InteropServices;
-public class WallpaperApi {
- [DllImport("user32.dll", CharSet=CharSet.Auto)]
- public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
-}
-"@ -ErrorAction SilentlyContinue
-
-# -----------------------------------------------------------------------
-# Collect system info
-# -----------------------------------------------------------------------
-Write-Log "Collecting system info"
-$hostname = $env:COMPUTERNAME
-$userDomain = $env:USERDOMAIN
-$userName = $env:USERNAME
-$loggedUser = if ($userDomain -and $userDomain -ne $hostname) { "$userDomain\$userName" } else { "$hostname\$userName" }
-
-$osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue
-$osName = if ($osInfo) { $osInfo.Caption -replace "^Microsoft\s*", "" } else { "Windows" }
-$ramGB = if ($osInfo) { [math]::Round($osInfo.TotalVisibleMemorySize / 1024 / 1024, 1) } else { "?" }
-
-$cpuInfo = Get-CimInstance Win32_Processor -ErrorAction SilentlyContinue | Select-Object -First 1
-$cpuCount = if ($cpuInfo) { $cpuInfo.NumberOfLogicalProcessors } else { "?" }
-$cpuSpeed = if ($cpuInfo) { $cpuInfo.MaxClockSpeed } else { "?" }
-
-$ips = (Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue |
- Where-Object { $_.IPAddress -ne "127.0.0.1" -and $_.PrefixOrigin -ne "WellKnown" } |
- Select-Object -ExpandProperty IPAddress) -join ", "
-if (-not $ips) { $ips = "N/A" }
-
-$csInfo = Get-CimInstance Win32_ComputerSystem -ErrorAction SilentlyContinue
-$domain = if ($csInfo -and $csInfo.PartOfDomain) { $csInfo.Domain } `
- elseif ($csInfo -and $csInfo.Workgroup) { $csInfo.Workgroup.ToLower() } `
- else { "N/A" }
-
-Write-Log "hostname=$hostname user=$loggedUser os=$osName ram=$($ramGB)GB cpu=${cpuCount}x${cpuSpeed}MHz ips=$ips domain=$domain"
-
-# -----------------------------------------------------------------------
-# Screen dimensions
-# -----------------------------------------------------------------------
-$screen = [System.Windows.Forms.Screen]::PrimaryScreen
-$width = if ($screen) { $screen.Bounds.Width } else { 1920 }
-$height = if ($screen) { $screen.Bounds.Height } else { 1080 }
-Write-Log "screen=${width}x${height}"
-
-# -----------------------------------------------------------------------
-# Create bitmap and graphics context
-# -----------------------------------------------------------------------
-$bmp = New-Object System.Drawing.Bitmap($width, $height)
-$g = [System.Drawing.Graphics]::FromImage($bmp)
-$g.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::AntiAlias
-$g.Clear([System.Drawing.ColorTranslator]::FromHtml("#556364"))
-
-# -----------------------------------------------------------------------
-# Fonts and brushes
-# -----------------------------------------------------------------------
-$fontName = "Segoe UI"
-$fontTitle = New-Object System.Drawing.Font($fontName, 36, [System.Drawing.FontStyle]::Bold)
-$fontBold = New-Object System.Drawing.Font($fontName, 14, [System.Drawing.FontStyle]::Bold)
-$fontReg = New-Object System.Drawing.Font($fontName, 14, [System.Drawing.FontStyle]::Regular)
-$brushWhite = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::White)
-$brushGray = New-Object System.Drawing.SolidBrush([System.Drawing.ColorTranslator]::FromHtml("#C8D2D2"))
-
-# -----------------------------------------------------------------------
-# Lines: text, font, brush
-# -----------------------------------------------------------------------
-$texts = @(
- $hostname
- "Logged on user: $loggedUser"
- "OS: $osName"
- "CPU: $cpuCount at $cpuSpeed MHz RAM: $($ramGB)GB"
- "IPv4 address: $ips Machine domain: $domain"
-)
-$fonts = @( $fontTitle, $fontReg, $fontBold, $fontReg, $fontReg )
-$brushes = @( $brushWhite, $brushGray, $brushGray, $brushGray, $brushGray )
-
-# -----------------------------------------------------------------------
-# Measure total block height, then center vertically
-# -----------------------------------------------------------------------
-$lineSpacing = 8
-$heights = @()
-for ($i = 0; $i -lt $texts.Count; $i++) {
- $heights += [int]($g.MeasureString($texts[$i], $fonts[$i]).Height)
-}
-$totalH = ($heights | Measure-Object -Sum).Sum + $lineSpacing * ($texts.Count - 1)
-$currentY = [int](($height - $totalH) / 2)
-
-# -----------------------------------------------------------------------
-# Draw each line centered horizontally
-# -----------------------------------------------------------------------
-for ($i = 0; $i -lt $texts.Count; $i++) {
- $sz = $g.MeasureString($texts[$i], $fonts[$i])
- $x = [int](($width - $sz.Width) / 2)
- $g.DrawString($texts[$i], $fonts[$i], $brushes[$i], [float]$x, [float]$currentY)
- $currentY += $heights[$i] + $lineSpacing
-}
-
-$g.Dispose()
-
-# -----------------------------------------------------------------------
-# Save and set as wallpaper
-# -----------------------------------------------------------------------
-$bmpPath = "C:\Windows\Setup\Scripts\desktopinfo.bmp"
-Write-Log "Saving BMP: $bmpPath"
-$bmp.Save($bmpPath, [System.Drawing.Imaging.ImageFormat]::Bmp)
-$bmp.Dispose()
-
-# Clear Windows wallpaper cache so it reloads from our BMP
-# Without this, Windows reuses TranscodedWallpaper and ignores the updated file
-$transcodedPath = "$env:APPDATA\Microsoft\Windows\Themes\TranscodedWallpaper"
-if (Test-Path $transcodedPath) {
- Remove-Item $transcodedPath -Force -ErrorAction SilentlyContinue
- Write-Log "Cleared TranscodedWallpaper cache"
-}
-
-# SPI_SETDESKTOPWALLPAPER=20, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE=3
-$result = [WallpaperApi]::SystemParametersInfo(20, 0, $bmpPath, 3)
-Write-Log "SystemParametersInfo result: $result"
-Write-Log "DesktopInfo render complete" -Level INFO
-'@
-
-$renderContent | Set-Content -Path $RenderScript -Encoding UTF8 -Force
-Write-Log "Render script written" -Level OK
-
-# -----------------------------------------------------------------------
-# Store deployment date in registry (used for reference)
-# -----------------------------------------------------------------------
-Write-Log "Storing deployment date in registry" -Level INFO
-try {
- if (-not (Test-Path "HKLM:\SOFTWARE\X9\Deployment")) {
- New-Item -Path "HKLM:\SOFTWARE\X9\Deployment" -Force | Out-Null
- }
- $existingDate = (Get-ItemProperty -Path "HKLM:\SOFTWARE\X9\Deployment" `
- -Name "DeployDate" -ErrorAction SilentlyContinue).DeployDate
- if (-not $existingDate) {
- Set-ItemProperty -Path "HKLM:\SOFTWARE\X9\Deployment" `
- -Name "DeployDate" `
- -Value (Get-Date -Format "yyyy-MM-dd") `
- -Force
- Write-Log " DeployDate set: $(Get-Date -Format 'yyyy-MM-dd')" -Level OK
- } else {
- Write-Log " DeployDate already set: $existingDate" -Level INFO
- }
-}
-catch {
- Write-Log " Failed to set DeployDate: $_" -Level ERROR
-}
-
-# -----------------------------------------------------------------------
-# Register scheduled task: DesktopInfo
-# Runs the render script on every user logon
-# -----------------------------------------------------------------------
-Write-Log "Registering task: DesktopInfo" -Level STEP
-
-try {
- Unregister-ScheduledTask -TaskName "DesktopInfo" -Confirm:$false -ErrorAction SilentlyContinue
-
- $action = New-ScheduledTaskAction -Execute "powershell.exe" `
- -Argument "-NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$RenderScript`""
- $trigger = New-ScheduledTaskTrigger -AtLogOn
- $trigger.Delay = "PT20S" # wait for network to be available
- $settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 2) `
- -MultipleInstances IgnoreNew `
- -StartWhenAvailable
- $principal = New-ScheduledTaskPrincipal -GroupId "Users" -RunLevel Limited
-
- $task = New-ScheduledTask -Action $action `
- -Trigger $trigger `
- -Settings $settings `
- -Principal $principal `
- -Description "Render system info onto desktop wallpaper on logon"
-
- Register-ScheduledTask -TaskName "DesktopInfo" -InputObject $task -Force | Out-Null
- Write-Log "Task DesktopInfo registered" -Level OK
-}
-catch {
- Write-Log "Failed to register DesktopInfo task: $_" -Level ERROR
-}
-
-# -----------------------------------------------------------------------
-# Run once immediately for current user
-# -----------------------------------------------------------------------
-Write-Log "Running DesktopInfo render now for current user" -Level INFO
-try {
- & powershell.exe -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File $RenderScript
- Write-Log "DesktopInfo rendered" -Level OK
-}
-catch {
- Write-Log "DesktopInfo render failed: $_" -Level WARN
-}
-
-Write-Log "Step 7 complete" -Level OK
diff --git a/flash/scripts/08-activation.ps1 b/flash/scripts/08-activation.ps1
deleted file mode 100644
index c3cbef3..0000000
--- a/flash/scripts/08-activation.ps1
+++ /dev/null
@@ -1,109 +0,0 @@
-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"
- Add-Content -Path $LogFile -Value $line -Encoding UTF8
-}
-
-# -----------------------------------------------------------------------
-# KMS Generic Volume License Keys (GVLK)
-# Source: https://docs.microsoft.com/en-us/windows-server/get-started/kms-client-activation-keys
-# These are official Microsoft-published keys for use with KMS infrastructure.
-# Replace with your MAK/retail key for standalone activation.
-# -----------------------------------------------------------------------
-$KmsKeys = @{
- # Windows 11
- "Windows 11 Pro" = "W269N-WFGWX-YVC9B-4J6C9-T83GX"
- "Windows 11 Pro N" = "MH37W-N47XK-V7XM9-C7227-GCQG9"
- "Windows 11 Pro Education" = "6TP4R-GNPTD-KYYHQ-7B7DP-J447Y"
- "Windows 11 Education" = "NW6C2-QMPVW-D7KKK-3GKT6-VCFB2"
- "Windows 11 Enterprise" = "NPPR9-FWDCX-D2C8J-H872K-2YT43"
- # Windows 10
- "Windows 10 Pro" = "W269N-WFGWX-YVC9B-4J6C9-T83GX"
- "Windows 10 Pro N" = "MH37W-N47XK-V7XM9-C7227-GCQG9"
- "Windows 10 Education" = "NW6C2-QMPVW-D7KKK-3GKT6-VCFB2"
- "Windows 10 Enterprise" = "NPPR9-FWDCX-D2C8J-H872K-2YT43"
- "Windows 10 Home" = "TX9XD-98N7V-6WMQ6-BX7FG-H8Q99"
-}
-
-# -----------------------------------------------------------------------
-# Check current activation status
-# -----------------------------------------------------------------------
-Write-Log "Checking Windows activation status" -Level INFO
-
-$licenseStatus = (Get-CimInstance SoftwareLicensingProduct -Filter "PartialProductKey IS NOT NULL AND Name LIKE 'Windows%'" -ErrorAction SilentlyContinue |
- Select-Object -First 1).LicenseStatus
-# LicenseStatus: 0=Unlicensed, 1=Licensed, 2=OOBGrace, 3=OOTGrace, 4=NonGenuineGrace, 5=Notification, 6=ExtendedGrace
-
-if ($licenseStatus -eq 1) {
- Write-Log " Windows is already activated - skipping" -Level OK
-} else {
- Write-Log " Activation status: $licenseStatus (not activated)" -Level WARN
-
- # Detect Windows edition
- $osCaption = (Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue).Caption
- Write-Log " Detected OS: $osCaption" -Level INFO
-
- # Check if a key is configured in config
- $customKey = $null
- if ($Config -and $Config.activation -and $Config.activation.productKey) {
- $customKey = $Config.activation.productKey
- }
-
- if ($customKey -and $customKey -ne "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX") {
- # Use key from config
- $keyToUse = $customKey
- Write-Log " Using product key from config" -Level INFO
- } else {
- # Find matching GVLK key by OS name
- $keyToUse = $null
- foreach ($entry in $KmsKeys.GetEnumerator()) {
- if ($osCaption -like "*$($entry.Key)*") {
- $keyToUse = $entry.Value
- Write-Log " Matched GVLK key for: $($entry.Key)" -Level INFO
- break
- }
- }
- }
-
- if (-not $keyToUse) {
- Write-Log " No matching key found for: $osCaption" -Level WARN
- Write-Log " Skipping activation - set activation.productKey in config.json" -Level WARN
- } else {
- # Install key
- Write-Log " Installing product key..." -Level INFO
- $ipkResult = & cscript //nologo "$env:SystemRoot\System32\slmgr.vbs" /ipk $keyToUse 2>&1
- if ($LASTEXITCODE -eq 0) {
- Write-Log " Key installed" -Level OK
- } else {
- Write-Log " Key install result: $ipkResult" -Level WARN
- }
-
- # Set KMS server if configured
- if ($Config -and $Config.activation -and $Config.activation.kmsServer) {
- $kmsServer = $Config.activation.kmsServer
- Write-Log " Setting KMS server: $kmsServer" -Level INFO
- & cscript //nologo "$env:SystemRoot\System32\slmgr.vbs" /skms $kmsServer 2>&1 | Out-Null
- }
-
- # Attempt activation
- Write-Log " Attempting activation..." -Level INFO
- $atoResult = & cscript //nologo "$env:SystemRoot\System32\slmgr.vbs" /ato 2>&1
- $atoOutput = $atoResult -join " "
-
- if ($atoOutput -match "successfully" -or $atoOutput -match "uspesn") {
- Write-Log " Activation successful" -Level OK
- } else {
- Write-Log " Activation result: $atoOutput" -Level WARN
- Write-Log " Activation may require a KMS server or valid MAK key" -Level WARN
- }
- }
-}
-
-Write-Log "Step 8 - Activation complete" -Level OK