diff --git a/CHANGELOG.md b/CHANGELOG.md index f7feab9..4528f2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,24 @@ Builds are continuous: every push to `main` produces a signed `xetup.exe` publis ## [Unreleased] -_Nothing yet._ +### Added +- **Bloatware feature toggles** (01): the bloatware step now exposes three GUI checkboxes - + `standardBloatware` (default on, the bulk AppX/capability/feature list), `removeNewOutlook` + (default on, the new Outlook for Windows app `Microsoft.OutlookForWindows`) and + `removeSnippingTool` (default OFF). Each toggle is independent, so a technician can spare + Outlook or remove the Snipping Tool without affecting the rest. + +### Changed +- **Snipping Tool now kept by default** (01): `Microsoft.ScreenSketch` (the modern Snipping Tool + app) plus the legacy capability and optional feature are no longer removed unless + `removeSnippingTool` is checked - it is a commonly used productivity tool, like Calculator. + Classic Outlook from M365 was never removed (it is a Win32 app, not an AppX package); only the + bundled new Outlook is, and that is now toggleable. + +### Fixed +- **`bloatware.keepPackages` was dropped at runtime**: the Go `Config` struct had no `Bloatware` + field, so the GUI's runtime-config regeneration silently discarded `keepPackages`. Added the + field so the keep-list survives and is honored by `01-bloatware.ps1`. ## [0.8] - 2026-06-02 diff --git a/SPEC.md b/SPEC.md index 7f6946e..04c4378 100644 --- a/SPEC.md +++ b/SPEC.md @@ -63,6 +63,15 @@ Removes ~35 AppX packages (Cortana, Copilot, Teams, Xbox, Skype, News, etc.), ~14 Windows Capabilities (Fax, IE, WordPad, etc.), and Optional Features (PowerShell 2.0, Recall). Calculator intentionally kept. +Three GUI feature toggles gate removal: +- `standardBloatware` (default on) - the bulk list above. +- `removeNewOutlook` (default on) - the new Outlook for Windows app + (`Microsoft.OutlookForWindows`). Classic Outlook from M365 is a Win32 app and + is never touched. +- `removeSnippingTool` (default OFF) - Snipping Tool across all three lists + (ScreenSketch app + legacy capability + legacy feature). Kept by default as a + common productivity tool, like Calculator. + --- ## Step 02 - Software installation @@ -184,7 +193,7 @@ properties (logging the raw objects printed "System.__ComObject"). "activation": { "productKey": "", "kmsServer": "" }, "software": { "install": [{ "name": "...", "wingetId": "..." }] }, "steps": { "adminAccount": true, ... }, - "features": { "software": { "wingetInstalls": true, "pdfDefault": true, "ateraAgent": true }, ... }, + "features": { "bloatware": { "standardBloatware": true, "removeNewOutlook": true, "removeSnippingTool": false }, "software": { "wingetInstalls": true, ... }, ... }, "bloatware": { "keepPackages": ["Microsoft.WindowsCalculator"] } } ``` diff --git a/config/config.json b/config/config.json index 58e1865..30d8380 100644 --- a/config/config.json +++ b/config/config.json @@ -33,6 +33,11 @@ "windowsUpdate": true }, "features": { + "bloatware": { + "standardBloatware": true, + "removeNewOutlook": true, + "removeSnippingTool": false + }, "software": { "wingetInstalls": true, "pdfDefault": true, diff --git a/internal/config/config.go b/internal/config/config.go index a4588a0..45abfc5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -14,6 +14,7 @@ type Config struct { Software Software `json:"software"` Steps map[string]bool `json:"steps"` Features Features `json:"features"` + Bloatware Bloatware `json:"bloatware"` } type Deployment struct { @@ -41,6 +42,12 @@ type Software struct { Install []SoftwareItem `json:"install"` } +// Bloatware holds bloatware-removal config. KeepPackages lists AppX package +// names that must never be removed, on top of the always-kept defaults. +type Bloatware struct { + KeepPackages []string `json:"keepPackages"` +} + // Features holds per-step, per-feature toggle flags. // Keys: stepID -> featureID -> enabled. // A missing key defaults to true (feature enabled). @@ -80,6 +87,11 @@ func DefaultConfig() Config { "windowsUpdate": true, }, Features: Features{ + "bloatware": { + "standardBloatware": true, + "removeNewOutlook": true, + "removeSnippingTool": false, + }, "software": { "wingetInstalls": true, "pdfDefault": true, @@ -102,6 +114,9 @@ func DefaultConfig() Config { "bios": true, }, }, + Bloatware: Bloatware{ + KeepPackages: []string{"Microsoft.WindowsCalculator"}, + }, } } diff --git a/internal/runner/runner.go b/internal/runner/runner.go index b0d78bd..591c0a0 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -58,6 +58,11 @@ type Feature struct { // have no sub-features and are controlled at the step level only. func StepFeatures() map[string][]Feature { return map[string][]Feature{ + "bloatware": { + {ID: "standardBloatware", Label: "Standardni bloatware (AppX, capabilities, features)"}, + {ID: "removeNewOutlook", Label: "Novy Outlook for Windows"}, + {ID: "removeSnippingTool", Label: "Vystrizky / Snipping Tool"}, + }, "software": { {ID: "wingetInstalls", Label: "Instalace SW ze seznamu (winget)"}, {ID: "pdfDefault", Label: "Adobe Reader jako vychozi PDF"}, diff --git a/scripts/01-bloatware.ps1 b/scripts/01-bloatware.ps1 index deb4750..92cfb45 100644 --- a/scripts/01-bloatware.ps1 +++ b/scripts/01-bloatware.ps1 @@ -12,6 +12,7 @@ zachovano-microsoft-windowscalculator: Calculator is explicitly excluded. Lightweight utility frequently used by technicians and end users. Removing it would require manual reinstall from Store. windows-capabilities-fax-ie-openssh-wmp-: Removed via Remove-WindowsCapability: Fax & Scan, Internet Explorer mode, OpenSSH client, Windows Media Player (legacy), WordPad, Handwriting recognition, Steps Recorder, Math Input Panel, Quick Assist. windows-optional-features-ps-2-0-mediapl: Disabled via Disable-WindowsOptionalFeature: PowerShell 2.0 (security risk - allows unsigned script execution bypass on older hosts), MediaPlayback, Windows Recall (AI screenshot surveillance), Snipping Tool optional component. + feature-toggles: Three GUI feature flags gate removal. standardBloatware (default on) covers the bulk list. removeNewOutlook (default on) controls Microsoft.OutlookForWindows; classic Outlook from M365 is a Win32 app and is never touched. removeSnippingTool (default OFF) controls Snipping Tool across all three lists (ScreenSketch app + legacy capability + legacy feature) - kept by default as a common productivity tool, like Calculator. #> param( [string]$ConfigPath, @@ -21,6 +22,33 @@ param( . "$PSScriptRoot\common.ps1" $Config = Load-Config $ConfigPath +# ----------------------------------------------------------------------- +# Feature flags (see CLAUDE.md features system) +# standardBloatware - removes the bulk AppX/capability/feature list +# removeNewOutlook - new Outlook for Windows (Microsoft.OutlookForWindows) +# removeSnippingTool - Snipping Tool, spans all three lists; default OFF +# Outlook and Snipping items are gated by their own flag, independent of the +# standard flag, so each GUI checkbox does exactly what it says. +# ----------------------------------------------------------------------- +$DoStandard = Get-Feature $Config "bloatware" "standardBloatware" $true +$DoOutlook = Get-Feature $Config "bloatware" "removeNewOutlook" $true +$DoSnipping = Get-Feature $Config "bloatware" "removeSnippingTool" $false + +# Snipping Tool appears as an AppX package (ScreenSketch, the modern app), +# a legacy capability, and a legacy optional feature. +$SnippingItems = @( + "Microsoft.ScreenSketch" + "Microsoft.Windows.SnippingTool" + "Microsoft-SnippingTool" +) + +function Test-RemovalAllowed { + param([string]$Name) + if ($Name -eq "Microsoft.OutlookForWindows") { return $DoOutlook } + if ($SnippingItems -contains $Name) { return $DoSnipping } + return $DoStandard +} + # ----------------------------------------------------------------------- # 1a - AppX packages # ----------------------------------------------------------------------- @@ -89,6 +117,10 @@ foreach ($pkg in $AppxToRemove) { Write-Log " KEEP $pkg" -Level INFO continue } + if (-not (Test-RemovalAllowed $pkg)) { + Write-Log " KEEP (feature off): $pkg" -Level INFO + continue + } # Installed packages (current user + all users) $installed = Get-AppxPackage -Name $pkg -AllUsers -ErrorAction SilentlyContinue @@ -145,6 +177,10 @@ Write-Log "1b - Removing Windows Capabilities" -Level STEP $installedCaps = Get-WindowsCapability -Online -ErrorAction SilentlyContinue foreach ($cap in $CapabilitiesToRemove) { + if (-not (Test-RemovalAllowed $cap)) { + Write-Log " KEEP (feature off): $cap" -Level INFO + continue + } # 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" @@ -177,6 +213,10 @@ $FeaturesToDisable = @( Write-Log "1c - Disabling Windows Optional Features" -Level STEP foreach ($feat in $FeaturesToDisable) { + if (-not (Test-RemovalAllowed $feat)) { + Write-Log " KEEP (feature off): $feat" -Level INFO + continue + } $feature = Get-WindowsOptionalFeature -Online -FeatureName $feat -ErrorAction SilentlyContinue if ($feature -and $feature.State -eq "Enabled") { try { diff --git a/web/data/descriptions.json b/web/data/descriptions.json index 7174632..0db5ba5 100644 --- a/web/data/descriptions.json +++ b/web/data/descriptions.json @@ -18,7 +18,8 @@ "appx-balicky-odstraneni-pro-vsechny-uziv": "Uses Remove-AppxPackage -AllUsers and Remove-AppxProvisionedPackage. The provisioned removal prevents apps from reinstalling for new user profiles. Covers ~35 apps including Cortana, Copilot, Teams personal, Xbox, Skype, News, Weather, Maps.", "zachovano-microsoft-windowscalculator": "Calculator is explicitly excluded. Lightweight utility frequently used by technicians and end users. Removing it would require manual reinstall from Store.", "windows-capabilities-fax-ie-openssh-wmp-": "Removed via Remove-WindowsCapability: Fax & Scan, Internet Explorer mode, OpenSSH client, Windows Media Player (legacy), WordPad, Handwriting recognition, Steps Recorder, Math Input Panel, Quick Assist.", - "windows-optional-features-ps-2-0-mediapl": "Disabled via Disable-WindowsOptionalFeature: PowerShell 2.0 (security risk - allows unsigned script execution bypass on older hosts), MediaPlayback, Windows Recall (AI screenshot surveillance), Snipping Tool optional component." + "windows-optional-features-ps-2-0-mediapl": "Disabled via Disable-WindowsOptionalFeature: PowerShell 2.0 (security risk - allows unsigned script execution bypass on older hosts), MediaPlayback, Windows Recall (AI screenshot surveillance), Snipping Tool optional component.", + "feature-toggles": "Three GUI feature flags gate removal. standardBloatware (default on) covers the bulk list. removeNewOutlook (default on) controls Microsoft.OutlookForWindows; classic Outlook from M365 is a Win32 app and is never touched. removeSnippingTool (default OFF) controls Snipping Tool across all three lists (ScreenSketch app + legacy capability + legacy feature) - kept by default as a common productivity tool, like Calculator." } }, "02-software": { diff --git a/web/spec/index.html b/web/spec/index.html index 4f0217d..7d3d66b 100644 --- a/web/spec/index.html +++ b/web/spec/index.html @@ -580,6 +580,9 @@