- config-editor.hta: lightweight WYSIWYG HTA editor for config.json - Step on/off toggles with info tooltips - Editable software list (winget packages) - Settings: timezone, admin account, desktopInfo, PDF default - Run.cmd: USB launcher with UAC auto-elevation and deployment menu - flash/: minimal USB-ready subset (Deploy, scripts, config, GUI, launcher) - config.json: add steps section for per-step enable/disable - Deploy-Windows.ps1: read steps from config, CLI switches override - 03-system-registry.ps1: add SearchOnTaskbarMode HKLM policy (Win11 search fix) - 04-default-profile.ps1: fix systray - clear TrayNotify cache + proper Explorer restart - 06-scheduled-tasks.ps1: fix Register-Task trigger array, ShowAllTrayIcons Win11 fix, PDF-DefaultApp runs as SYSTEM via HKCR (bypasses UserChoice Hash validation) - 02-software.ps1: remove unreliable UserChoice ProgId write without Hash Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
185 lines
5.8 KiB
PowerShell
185 lines
5.8 KiB
PowerShell
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"
|
|
"Microsoft-RemoteDesktopConnection"
|
|
"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
|