Windows 10: remove applications from the uninstall list
Posted by jpluimers on 2021/11/04
After doing Windows upgrades to Windows 10, every now and then I bump into applications that do not fully uninstall themselves and get stuck on the uninstall list (that you get when running appwiz.cpl
or browse to the Control Pannel installed programs list).
[WayBack] How to Manually Remove Programs from the Add/Remove Programs List mentions to inspect registry key HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
, but that didn’t include some of the applications.
Then I found [WayBack] Remove entry from Windows 10 Apps & Features – Super User, where the answers mentions two other keys (thanks users [WayBack] Kreiggott and [WayBack] NutCracker):
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
Neat!
So I made the below PowerShell script to dump installed programs.
It grabs the list of registry keys containing installed software and their registry values, then empirically filters out most values that are also now shown in AppWiz.cpl
.
Like database work, the values can have properties having a value or being null. So it’s SQL like expression galore to do the filtering.
This post is slightly related to Still unsolved since 2015 NetBeans: Bug 251538 – Your Installer is Creating Invalid Data for the NoModify DWORD Key which crashes enumeration of the Uninstall Key in at least PowerShell, where I already did (without documenting) some Uninstall
spelunking.
## The collection of registry keys gives Name and Property of each registry key; where Property is compound containing all registry values of that key. ## Get-ItemProperty will get you all the values on which you can filter, including a few special PS* values that allow you to browse back to the registry key. # x86 installs on x64 hardware: http://stackoverflow.com/questions/12199372/get-itemproperty-not-returning-all-properties/12200100#12200100 $nonUninstallableSoftwareRegistryKeys = (@ (Get-Item HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*)) + (Get-Item HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*) + (Get-Item HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*) #$nonUninstallableSoftwareRegistryKeys.GetType().FullName #$nonUninstallableSoftwareRegistryKeys | Get-Member #$nonUninstallableSoftwareRegistryKeys | Out-GridView #$nonUninstallableSoftwareRegistryKeys | Get-ItemProperty | Get-Member #$nonUninstallableSoftwareRegistryKeys | Get-ItemProperty | Out-GridView #Return $nonUninstallableSoftwareRegistryNameValues = $nonUninstallableSoftwareRegistryKeys | Get-ItemProperty | Where-Object { $_.SystemComponent -ne 1 -and $_.NoRemove -ne 1 -and $_.UninstallString -ne "" -and $_.UninstallString -ne $null } # Filters out most things that AppWiz.cpl will leave out as well. # Might need more fine tuning, but is good enough for now. # PSPath shows the path to the underlying registry key of each value $nonUninstallableSoftwareRegistryNameValues | Select-Object SystemComponent, NoRemove, DisplayName, DisplayVersion, UninstallString, PSChildName <#, PSPath #> | Sort-Object DisplayName | Out-GridView # Need to find a good way to output this in a really wide Format-Table text format.
–jeroen
Leave a Reply