Manually Remove a Service with PowerShell

From time to time, you’ll be faced with a piece of software whose uninstall is poorly written, a virus or malware, or a freak power failure during an uninstall. In instances like these, you might have to remove an orphaned service in Windows. In my particular case, our old monitoring software was Zenith Infotech, and their software left behind two services that can really booger up an Exchange server if you don’t get rid of them.

The first thing you need to do is open up Server Manager, and drill down to the server’s services and get the name of the service(s) you need to remove by right clicking on the service and selecting properties from the sub menu:

At this point, I personally opened up regedit and verified the location of the service in the registry for sanity’s sake:

Now we have the information we need to delete the service. If you have just one service on one server, then you can just delete the service’s registry key from Registry Editor and be done with it. Since I have over 90 servers I need to do this for, I strung together these PowerShell commands to remove these services.

The first thing I decided to do was stop the service, just in case it was actually trying to do something to the OS:

Stop-Service SAAZappr

The next command identifies the registry key to be removed (everything after the HKLM: part as it appears in the bottom of the Registry Editor window highlighted above) and removes it, and by adding the –Recurse switch, we’re also telling it to automatically remove all of its sub-containers, keys and parts. For good measure, I tagged –Force on the end in the event some sort of permissions issue decided to rear its ugly head:

Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services\SaaZAppr | Where-Object {$_.PSChildName -ne ‘CLSID’} | Remove-Item –Force

Finally, I took the data from the “ImagePath” section of the Registry Key and made sure I deleted all of the folders, subfolders, and files etc. from the server that were also potentially left behind, also using the –Recurse and –Force switches:

Remove-Item “C:\program files\SAAZOD” -Recurse –Force

The last thing I did was compile the script into an .exe to ease deployment on all of my servers. I complied into an .exe using PowerGUI Pro.

So, the final script, removing both of the SAAZ services, covering both 32 and 64 bit installations, looked like this:

# SaaZ Services Killer

# Written by Matt Richardson

# 02/14/2012

Stop-Service SAAZappr

Stop-Service SAAZapsc

Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services\SaaZAppr | Where-Object {$_.PSChildName -ne ‘CLSID’} | Remove-Item -Force 

Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services\SaaZapsc | Where-Object {$_.PSChildName -ne ‘CLSID’} | Remove-Item -Force

Remove-Item “C:\program files\SAAZExmonScripts” -Recurse -Force

Remove-Item “C:\program files\SAAZOD” -Recurse -Force

Remove-Item “C:\program files (x86)\SAAZExmonScripts” -Recurse -Force

Remove-Item “C:\program files (x86)\SAAZOD” -Recurse –Force

This script will get an error every time since it is trying to delete both 32 bit and 64 bit installation folders, but the errors are ambiguous and don’t stop the script from completing so I didn’t see the harm in it or the value in building in the logic to identify the version and delete accordingly.