Skip to content

Commit 88f8234

Browse files
committed
Update Remove-AppxApps.ps1
Adds packages to filter out in default mode. Adds ConfirmImpact to require administrator to validate the remove action
1 parent f93e73f commit 88f8234

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

src/Remove-AppxApps.ps1

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535
- The script must be run with elevated privileges to remove provisioned packages and delete specific registry keys.
3636
- The script checks the operating system version to determine whether it is running on Windows 10 or Windows 11 and adjusts the removal process accordingly.
3737
#>
38-
39-
[CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = "Default")]
38+
[CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = "Default", ConfirmImpact = "High")]
4039
param (
4140
[Parameter(Mandatory = $false, ParameterSetName = "Default")]
4241
[System.Collections.ArrayList] $SafePackageList = @(
@@ -52,6 +51,7 @@ param (
5251
"Microsoft.WindowsSoundRecorder_8wekyb3d8bbwe", # Voice recording app
5352
"Microsoft.WindowsTerminal_8wekyb3d8bbwe", # Essential terminal app
5453
"Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe", # Microsoft Edge browser
54+
"Microsoft.Edge.GameAssist_8wekyb3d8bbwe", # Microsoft Edge browser component
5555
"Microsoft.ZuneMusic_8wekyb3d8bbwe", # Windows Media Player, video and music player
5656

5757
# System applications
@@ -60,12 +60,15 @@ param (
6060
"Microsoft.ApplicationCompatibilityEnhancements_8wekyb3d8bbwe",
6161
"Microsoft.SecHealthUI_8wekyb3d8bbwe",
6262
"Microsoft.StorePurchaseApp_8wekyb3d8bbwe",
63+
"Microsoft.StartExperiencesApp_8wekyb3d8bbwe",
6364
"Microsoft.Wallet_8wekyb3d8bbwe",
6465
"MicrosoftWindows.CrossDevice_cw5n1h2txyewy",
6566
"MicrosoftWindows.Client.WebExperience_cw5n1h2txyewy",
66-
"Microsoft.WidgetsPlatformRuntime_8wekyb3d8bbwe",
67-
"MicrosoftCorporationII.WinAppRuntime.Main.1.5_8wekyb3d8bbwe",
67+
"Microsoft.WidgetsPlatformRuntime_8wekyb3d8bbwe", # Ensure policy disables Widgets
6868
"MicrosoftCorporationII.WinAppRuntime.Singleton_8wekyb3d8bbwe",
69+
"Microsoft.Winget.Source_8wekyb3d8bbwe", # Winget package
70+
"Microsoft.WindowsPackageManagerManifestCreator_8wekyb3d8bbwe", # App to create manifests for winget
71+
"Microsoft.OneDriveSync_8wekyb3d8bbwe", # OneDrive sync client
6972

7073
# Image & video codecs
7174
"Microsoft.MPEG2VideoExtension_8wekyb3d8bbwe",
@@ -78,6 +81,14 @@ param (
7881
"Microsoft.WebMediaExtensions_8wekyb3d8bbwe",
7982
"Microsoft.WebpImageExtension_8wekyb3d8bbwe"),
8083

84+
[Parameter(Mandatory = $false, ParameterSetName = "Default")]
85+
[System.Collections.ArrayList] $SafePackageWildCard = @(
86+
# Packages that include version numbers, so static names aren't effective
87+
"MicrosoftCorporationII.WinAppRuntime.Main*",
88+
"Microsoft.WinAppRuntime.DDLM*",
89+
"Microsoft.LanguageExperiencePack*",
90+
"Microsoft.Teams.SlimCoreVdi*"),
91+
8192
# Use Targeted switch to remove a targeted list of packages. Useful for in-place feature updates
8293
[Parameter(Mandatory = $false, ParameterSetName = "Targeted")]
8394
[System.Management.Automation.SwitchParameter] $Targeted,
@@ -98,14 +109,31 @@ param (
98109
"Microsoft.XboxGameOverlay_8wekyb3d8bbwe",
99110
"Microsoft.XboxIdentityProvider_8wekyb3d8bbwe",
100111
"Microsoft.XboxSpeechToTextOverlay_8wekyb3d8bbwe",
101-
# "MSTeams_8wekyb3d8bbwe",
112+
"MSTeams_8wekyb3d8bbwe",
102113
"Microsoft.ZuneVideo_8wekyb3d8bbwe")
103114
)
104115

105116
begin {
106-
# Get elevated status. if elevated we'll remove packages from all users and provisioned packages
107-
$Role = [Security.Principal.WindowsBuiltInRole] "Administrator"
108-
[System.Boolean] $Elevated = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole($Role)
117+
#region Functions
118+
function Test-IsOobeComplete {
119+
# https://oofhours.com/2023/09/15/detecting-when-you-are-in-oobe/
120+
$TypeDef = @"
121+
using System;
122+
using System.Text;
123+
using System.Collections.Generic;
124+
using System.Runtime.InteropServices;
125+
namespace Api {
126+
public class Kernel32 {
127+
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
128+
public static extern int OOBEComplete(ref int bIsOOBEComplete);
129+
}
130+
}
131+
"@
132+
Add-Type -TypeDefinition $TypeDef -Language "CSharp"
133+
$IsOOBEComplete = $false
134+
[Void][Api.Kernel32]::OOBEComplete([ref] $IsOOBEComplete)
135+
return [System.Boolean]$IsOOBEComplete
136+
}
109137

110138
function Add-DeprovisionedPackageKey {
111139
# Explicitly create the registry key for deprovisioned packages
@@ -125,6 +153,15 @@ begin {
125153
Write-Verbose -Message "Failed to create registry key: $Path. Error: $($_.Exception.Message)"
126154
}
127155
}
156+
#endregion
157+
158+
# Get elevated status. if elevated we'll remove packages from all users and provisioned packages
159+
$Role = [Security.Principal.WindowsBuiltInRole] "Administrator"
160+
[System.Boolean] $Elevated = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole($Role)
161+
162+
if (Test-IsOobeComplete) {
163+
Write-Warning -Message "OOBE is complete. Removing applications on an existing desktop may remove applications that users rely on."
164+
}
128165
}
129166

130167
process {
@@ -157,6 +194,15 @@ process {
157194
# Remove all AppX packages, except for packages that can't be removed, frameworks, and the safe packages list
158195
$AppxPackagesToRemove = $AppxPackages | `
159196
Where-Object { $_.NonRemovable -eq $false -and $_.IsFramework -eq $false -and $_.PackageFamilyName -notin $SafePackageList }
197+
198+
# Further filter out packages that match the safe wildcard patterns
199+
$MatchingPackages = $AppxPackagesToRemove | Where-Object {
200+
$Package = $_.PackageFamilyName
201+
$SafePackageWildCard | Where-Object { $Package -like $_ }
202+
}
203+
if ($MatchingPackages) {
204+
$AppxPackagesToRemove = $AppxPackagesToRemove | Where-Object { $_.PackageFamilyName -notin $MatchingPackages.PackageFamilyName }
205+
}
160206
Write-Verbose -Message "We found $($AppxPackagesToRemove.Count) packages to remove."
161207

162208
# Check if we're running on Windows 11 or Windows Server 2025, or above

0 commit comments

Comments
 (0)