<# .SYNOPSIS Removes pre-installed bloatware: AppX packages, Capabilities, and Optional Features. .DESCRIPTION Removes Microsoft-bundled apps and features not needed in a business MSP deployment. Removal is done for all users (-AllUsers) and from the provisioning store so new users do not get them either. Calculator is intentionally kept. .ITEMS 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. #> 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