Easy removal of preinstalled bloatware using PowerShell

Ondrej SebelaOndrej Sebela
2 min read

Recently I came into a situation where I needed to provision new Dell Precision laptops for our employees. This laptop comes with a lot of preinstalled applications (bloatware) so I was looking for some simple but efficient way to silently remove them. And by efficient I mean avoiding the need to manually find an uninstall command for each preinstalled application.

As always PowerShell and registry property QuietUninstallString were my saviors ๐Ÿ˜‰.


TL;DR

Use function Get-InstalledSoftware and Uninstall-ApplicationViaUninstallString functions from my CommonStuff PS module like ๐Ÿ‘‡

# Uninstall every application that has 'Dell' in its name.
Get-InstalledSoftware -appName Dell | Uninstall-ApplicationViaUninstallString

Find silent uninstall command the smart way

As you probably know, a list of installed applications is stored in two registry keys: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall. What you might not know is that almost every application that is stored there has defined properties QuietUninstallString and/or UninstallString. Applications installed via EXE have typically both these properties but MSI have just UninstallString.

EXE installed application ๐Ÿ‘‡ image.png

MSI installed application ๐Ÿ‘‡ image.png

Drawbacks of this solution

  • Sometimes for MSI installed applications UninstallString property contains /I instead of /X parameter (/I means 'install' and /X means 'uninstall')
  • Some EXE application (like "Dell Optimizer Service") has the QuietUninstallString property but when used, it normally runs uninstall wizard GUI. Hence there is no guarantee that QuietUninstallString will really start silent uninstallation ๐Ÿ˜ž.
    • To help with that I've added the parameter addArgument to the Uninstall-ApplicationViaUninstallString function (in the case of the "Dell Optimizer Service" application mentioned before I've added -silent parameter to the uninstall command).

Summary

With the information above in mind, I've created two functions that work together: Uninstall-ApplicationViaUninstallString and Get-InstalledSoftware. Both of them can be found in my CommonStuff PS module and be used like this ๐Ÿ‘‡. image.png

Both also support TAB-completion, so it is super easy to get the app name. image.png

Just in case you are curious, my final solution for the Dell Precision laptops looks like this:

$SWName = Get-InstalledSoftware "Dell", "Microsoft Update Health Tools", "ExpressConnect Drivers & Services" | ? DisplayName -NotLike "Dell Command | Update for Windows*" | select -ExpandProperty DisplayName

if ($SWName) {
    try {
        $SWName | % {
            $param = @{
                Name        = $_
                ErrorAction = "Stop"
            }

            if ($_ -eq "Dell Optimizer Service") {
                # uninstallation isn't unattended without -silent switch
                $param.addArgument = "-silent"
            }

            Uninstall-ApplicationViaUninstallString @param
        }
    } catch {
        Write-Error "There was an error when uninstalling bloatware: $_"
    }
} else {
    "There is no bloatware detected"
}
0
Subscribe to my newsletter

Read articles from Ondrej Sebela directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ondrej Sebela
Ondrej Sebela

I work as System Administrator for more than 10 years now and I love to make my life easier by automating work & personal stuff via PowerShell (even silly things like food recipes list generation).