Removing the Windows apps that won’t uninstall: VPN drivers, Npcap, and the credential provider on every sign-in
Every desktop engineer has a list of apps that won’t die. The VPN client whose network driver outlives the software itself. The packet-capture driver a developer installed years ago. The SSO agent that ships a credential provider you’d love to get rid of, if you could do it without locking people out of their PCs.
I spent years cleaning these up by hand across a fleet of about 30,000 Windows endpoints, with a bit of help from NirSoft’s RegScanner. I finally put all of it into a script: Kill It With Fire. It’s free and open source. Below is what I ran into building it, since most of it applies whether you use the script or clean up by hand.
An uninstaller only removes what the installer remembers
The uninstaller removes what the vendor’s installer recorded. Anything the app or its drivers created at runtime, and anything an older version left behind, stays. If the uninstaller hangs, waits for a click nobody’s there to give, or is broken, nothing gets removed at all.
To see what gets left, I installed the usual suspects on Hyper-V lab VMs, removed them, and compared each machine with a snapshot taken before the app went on.
FortiClient: adapters that come back after a reboot
FortiClient VPN installs three things that matter here:
- Network components in the network stack (what
netcfgmanages). - A driver package in the driver store (
C:\Windows\INF\oemNN.inf). - Software-created devices: virtual adapters that show up in Device Manager like real hardware.
The uninstaller doesn’t get all of it. If the devices and the driver package are still there, Plug and Play finds the device at the next boot, matches it to the driver in the store, and the adapter is back.
The order that works:
- Remove the network components (
netcfg -u). - Remove the devices the app’s own driver created (
pnputil /remove-device). Never real hardware. - Delete the driver package from the store (
pnputil /delete-driver). - Remove the driver service and its files.
Delete the package while its devices still exist and the store won’t let go of it. Skip the devices and they come back. I hit that one in the lab this week.
To tell the app’s devices apart from a real network card, the script reads the app’s own .inf files (in its install folder, plus any copies in the driver store with the same hash) and matches the hardware IDs and services they install. A device created by the app’s INF is the app’s. A driver that also serves real hardware stays.
Npcap and VirtualBox
Npcap, the packet-capture driver behind Wireshark, installs an NDIS filter and a couple of drivers. Its uninstaller handles most of it, but it left a service key called npcap_wifi behind with nothing in it but Start=4. No type, no image path. sc delete says there’s no such service, so a cleanup script that treats every key under Services as a service stops halfway. Kill It With Fire only acts on a service key that has a service type.
VirtualBox left VBoxNetAdp6.sys, a network driver file owned by TrustedInstaller. An administrator can’t move it without taking ownership first. Taking ownership is easy. Putting the file back on a restore with its original owner and permissions is the part that matters, or you’ve weakened a system file’s security without noticing. The script saves the file’s security descriptor before it touches anything and writes it back exactly on restore.
Credential providers: don’t lock anyone out
SSO agents like Imprivata hook into Windows sign-in with a credential provider (it draws a sign-in tile) and usually a credential provider filter, which can hide or wrap other providers, including the normal password tile. Some setups turn the built-in password provider off completely, so the vendor’s tile is the only way in.
Remove the provider but leave the filter, and the filter can still hide the password tile. Remove the provider while the password provider is still turned off, and nobody can sign in to that machine. Do that on a nursing unit’s PCs and you have an incident.
The order:
- Turn the built-in password sign-in back on first, if the app turned it off.
- Remove the app’s credential provider filters.
- Remove its credential providers.
- Remove the rest of its logon hooks (Winlogon, LSA, network provider entries).
All of this runs before services, drivers and files, so a run that stops part way can’t leave a machine nobody can log in to. In the lab, after removing Imprivata, the credential providers and filters matched the snapshot from before it was installed, and the standard Windows sign-in screen came back.
Remove what points at a thing before the thing itself
The same rule shows up across all of these:
- A device filter that names a deleted driver stops every device in that class at the next boot. A keyboard class filter pointing at a missing driver means no keyboard. Filters go before their drivers.
- Services stop before their drivers, so the driver can unload without a reboot.
- Files go last, once nothing loads them. A file that’s still in use moves at the next boot instead.
What Kill It With Fire does
Two ways to run it:
- The proper way (the default): the app’s own uninstaller runs first, silently. For an EXE, it picks the silent switch from the engine that built the uninstaller (NSIS, Inno Setup, InstallShield and so on). Then it cleans up what’s left.
- KILL IT WITH FIRE: skip the uninstaller and go straight to the cleanup. For when the uninstaller is the problem.
Either way:
- It scans first, and a scan changes nothing. Every item in the plan comes with the evidence that ties it to the app. Weak evidence, like a driver that only claims the same vendor, is marked uncertain and left alone unless you opt in.
- It backs everything up, and Restore puts the run back.
- It refuses Microsoft software, security agents and Windows itself. If you need your EDR gone, talk to your EDR vendor. The report names the removal tool to ask for.
It’s one signed PowerShell file. There’s a window if you want to click through it, and a command line with exit codes for Intune, PDQ or your RMM.
Read the warning before you run it. It runs as admin because it has to, so it can do real damage if you don’t know what you’re doing. Scan first, read the plan, try it on a VM before your fleet, and leave the backup on. I test every change in the lab and on a throwaway GitHub runner, and it still isn’t perfect. If it breaks something, the backup is there, and I want to hear about it.
Get Kill It With Fire: free, MIT, source on GitHub. If you need an app gone from 500 machines at once, RFF does that from a browser tab, free up to 100 endpoints.