ENGINEERING

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:

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:

  1. Remove the network components (netcfg -u).
  2. Remove the devices the app’s own driver created (pnputil /remove-device). Never real hardware.
  3. Delete the driver package from the store (pnputil /delete-driver).
  4. 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:

  1. Turn the built-in password sign-in back on first, if the app turned it off.
  2. Remove the app’s credential provider filters.
  3. Remove its credential providers.
  4. 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:

What Kill It With Fire does

Two ways to run it:

Either way:

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.