From 8ce9518d516805948c2c540e0a4d95be4c10bcf3 Mon Sep 17 00:00:00 2001 From: Claire Davis Date: Mon, 9 May 2022 13:37:18 -0700 Subject: [PATCH] Initial commit --- README.md | 20 +++++++- remove-apps.ps1 | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 remove-apps.ps1 diff --git a/README.md b/README.md index 8b6f029..05c9d62 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,19 @@ -# Remove-Default-Apps +# Remove Default Apps -Uninstalls (and deregisters) Windows APPX packages that are preinstalled by default. \ No newline at end of file +This script makes it simple to remove unnecessary Microsoft, OEM, and third-party modern app packages (APPX) which are typically preinstalled and part of an OS image. + +There are two different means of removing packages: + 1. `Remove-AppxPackage` uninstalls packages installed for the current user. + 2. `Remove-AppxProvisionedPackage -Online` uninstalls *staged* packages - these packages are automatically deployed every time a new user profile is created. + +**Be careful removing staged packages.** It's typically possible to redownload these packages from the Microsoft Store, but this isn't a given for every package. Windows prevents uninstalling core system packages, so you can't render your Windows installation unusable by accidentally removing a staged pacakge, but it's always best practice to assess every package presented by the script. + +The `$appcsv` variable contains a single, multiline, comma-delimited string. By default, this list only includes Microsoft packages. + +There are three fields: +1. **name** - The display name for the package. This is typically a dot-separated string, such as `Microsoft.Windows.Photos`. +2. **id** - The Store ID for the package. If you use this script to reinstall previously-uninstalled packages, you need this ID to find the package in the Store. This ID may be obtained by finding the app in the Microsoft Store through a web browser. The ID is part of the URL for the app listing: +`https://www.microsoft.com/en-us/p/package-name/abc123packageid?...` +3. **skip** - A Boolean value; if true, the script will bypass this package, leaving it intact. + +Edit `$appcsv` to add packages for removal, and to flag packages to be skipped the next time you run the app. You can also edit the boolean value after starting the script; look at the contents `$applist` while running the script. \ No newline at end of file diff --git a/remove-apps.ps1 b/remove-apps.ps1 new file mode 100644 index 0000000..3f9bcf7 --- /dev/null +++ b/remove-apps.ps1 @@ -0,0 +1,120 @@ +Clear-Host + +$apps = Get-AppxProvisionedPackage -Online +$apxs = Get-AppPackage -AllUsers + +$store = "ms-windows-store://pdp/?ProductId=" + +$appcsv = @("name,id,skip +Microsoft.BingWeather,9WZDNCRFJ3Q2,0 +Microsoft.GetHelp,9PKDZBMV1H3T,0 +Microsoft.Getstarted,9WZDNCRDTBJJ,0 +Microsoft.Microsoft3DViewer,9NBLGGH42THS,0 +Microsoft.MicrosoftOfficeHub,9WZDNCRD29V9,0 +Microsoft.MicrosoftSolitaireCollection,9WZDNCRFHWD2,0 +Microsoft.MicrosoftStickyNotes,9NBLGGH4QGHW,0 +Microsoft.MixedReality.Portal,9NG1H8B3ZC7M,0 +Microsoft.MSPaint,9PCFS5B6T72H,0 +Microsoft.Office.OneNote,9WZDNCRFHVJL,0 +Microsoft.People,9NBLGGH10PG8,0 +Microsoft.ScreenSketch,9MZ95KL8MR0L,0 +Microsoft.SkypeApp,9WZDNCRFJ364,0 +Microsoft.Windows.Photos,9WZDNCRFJBH4,0 +Microsoft.WindowsAlarms,9WZDNCRFJ3PR,0 +Microsoft.WindowsCalculator,9WZDNCRFHVN5,0 +Microsoft.WindowsCamera,9WZDNCRFJBBG,0 +microsoft.windowscommunicationsapps,9WZDNCRFHVQM,0 +Microsoft.WindowsFeedbackHub,9NBLGGH4R32N,0 +Microsoft.WindowsMaps,9WZDNCRDTBVB,0 +Microsoft.WindowsSoundRecorder,9WZDNCRFHW,0 +Microsoft.YourPhone,9NMPJ99VJBWV,0 +Microsoft.XboxApp,9WZDNCRFJBD8,0 +Microsoft.XboxIdentityProvider,9WZDNCRD1HKW,0 +Microsoft.ZuneMusic,9WZDNCRFJ3PT,0 +Microsoft.ZuneVideo,9WZDNCRFJ3P2,0 +") + +# Windows 11 additions +if ([System.Environment]::OSVersion.Version.Major -eq 11) { + $appcsv += @(" + MicrosoftWindows.Client.WebExperience,0 + SpotifyAB.SpotifyMusic,0, + Disney.37853FC22B2CE,0, + 26720RandomSaladGamesLLC.SimpleSolitaire,0, + 5A894077.McAfeeSecurity,0, + C27EB4BA.DropboxOEM,0, + Microsoft.MinecraftEducationEdition,0 + ") +} + +$applist = ConvertFrom-Csv $appcsv + +$missed = @() + +Write-Host @("This script will remove selected default Windows app packages. +It's most useful when your Windows drive is small, and you need to conserve space. + +You may remove staged or user packages, or you may remove both simultaneously. + +USER packages are, as the name implies, installed on a per-user basis. You can easily reinstall +these from the regular Microsoft Store app and website. This script can help you find the +right packages in the Store app for easy reinstallation. + +STAGED packages are part of the default Windows user profile, which means they will +automatically install for every user who logs into the local machine, regardless of how +they log in (local, domain, MSA, AAD). + +====== WARNING ====== +Once you remove STAGED packages, there's no easy way to re-add them to the default profile! +Only use this option when you're certain you never want a package ever auto-installing. +") + +$q = Read-Host "Remove [U]ser packages, [S]taged packages, or [B]oth?" + +switch ($q) { + {"u","s","b"} { + # this is good, proceed + + foreach($app in $applist) { + # if skip = 1, continue + if($app.skip) { continue } + # check if exists in installed and staged lists + if(($apps.DisplayName -contains $app.name) -or ($apxs.Name -contains $app.name)) { + $remq = Read-Host "Remove $($app.name)?" + if($remq) { + switch ($q) { + {"u","b"} { + # user and both + Get-AppxPackage -AllUsers -Name $app.name | Remove-AppxPackage + } + {"s","b"} { + # staged and both + Get-AppxProvisionedPackage -Online | ? { $_.DisplayName -eq $app.name } | + Remove-AppxProvisionedPackage -Online + } + } + } + } + elseif($apxs.Name -notcontains $app.name) { + $missed += $app + } + } + Write-Host "" + } + default { + Write-Host "No valid option selected." + } +} + +if($missed.Count -gt 0) { + $q2 = Read-Host "Prompt to reinstall $($missed.Count) missing USER packages?" + + if($q2) { + foreach($m in $missed) { + $remq2 = Read-Host "Reinstall $($m.name)?" + if($remq2) { + Start-Process ($store + $m.id) + } + } + } +} \ No newline at end of file