02-software: add Atera RMM agent install (Invoke-WebRequest + msiexec /qn), stop UCPD driver before PDF association write, restart after; remove reference to PDF-DefaultApp scheduled task in header 03-system-registry: correct OneDrive uninstall description - intentional (pre-installed consumer version only, no policy key, M365 can reinstall) 04-default-profile: OneDrive RunOnce blocking removed, ShowRecent=0, ShowFrequent=0, FullPath=1 in CabinetState already added in prior session 06-scheduled-tasks: PDF-DefaultApp task removed - PDF set once in step 02 08-activation: add OA3/BIOS embedded key check via SoftwareLicensingService WMI; key priority: config.json > OA3 firmware > GVLK web/spec: update all status badges, remove mustfix flags, deduplicate OneDrive entries across steps 01/03/04, add OA3 row to step-08 web/data/descriptions.json: regenerated (65 items) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
202 lines
7.6 KiB
PowerShell
202 lines
7.6 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. RDP client and
|
|
OneDrive are NOT removed here - they are required for business use.
|
|
|
|
.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.
|
|
microsoft-remotedesktopconnection-nesmi-: The RDP client optional feature is explicitly NOT in the removal list. Must remain functional for MSP remote access, TeamViewer alternatives, and client IT management tasks.
|
|
onedrive-nesmi-byt-odstranovano-tady: OneDrive removal is NOT done here. OneDrive must remain available for Microsoft 365 / SharePoint deployment. Any OneDrive removal lines in this script are incorrect and must be removed.
|
|
#>
|
|
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
|