- Write-Log creates C:\Windows\Setup\Scripts\ automatically (was failing on fresh install) - Step 12: PSWindowsUpdate first pass + X9-WindowsUpdate scheduled task for post-reboot rounds (handles typical 2-3 reboot cycles on fresh Windows, task self-deletes when up to date) - GUI summary: 60s countdown auto-reboot with "Restartovat ted" / "Zrusit restart" buttons - runner: HideWindow=true prevents PS console from appearing over GUI - runner: skipPSNoiseLine filters PS error metadata (CategoryInfo, FullyQualifiedErrorId etc.) - web: fix curl command to include https:// prefix
200 lines
7.2 KiB
PowerShell
200 lines
7.2 KiB
PowerShell
<#
|
|
.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"
|
|
$null = New-Item -ItemType Directory -Force -Path (Split-Path $LogFile -Parent) -ErrorAction SilentlyContinue
|
|
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
|