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.


Clean Up Orphaned Calendar Items in Exchange 2007

Updated 3/29/2012

A common problem I’ve read about, and personally experienced, is deleting a user and their mailbox, only to find out later that they had a recurring calendar meeting in a conference room, or they were an administrative assistant, or something like that. This will cause orphaned calendar items that can be a pain to clean up. When I recently ran into this problem, I noodled around trying to find an answer. I found forums on Microsoft’s site, Experts-Exchange, etc. with nothing that was really helpful. Finally, I hit up a peer of mine, Robert Durkin. Robert sent me this link of a post by Dominic Savio that got me going in the right direction.

Dominic’s post covered the basics and had the information I needed, but it still required some playing to get what I needed. So, I ended up with three commands to clean up old orphaned calendar items:

Command 1:

Export-Mailbox -Identity <user alias> -SenderKeywords “” -IncludeFolders “\Calendar” –DeleteContent

This command will delete all calendar appointments originating from the deleted user in a single target mailbox using that deleted user’s email address. This will ensure that only calendar appointments from that user will be deleted since we’re A) using a unique string to identify the appointments and B) specifying the Calendar folder. Be careful if you’ve added the departed user’s email as an alias to another account because I didn’t test that and I am not sure what those results would be.

Command 2:

Get-Mailbox | Export-Mailbox -SenderKeywords “” -IncludeFolders “\Calendar” –DeleteContent

This command will delete calendar appointments originating from the deleted user in every mailbox, in the unlikely event they were meeting happy.

Command 3:

Get-Mailbox -Filter {CustomAttribute14 -eq ‘ResourceMB’} | Export-Mailbox -SenderKeywords “” -IncludeFolders “\Calendar” –DeleteContent

I borrowed the filter portion of my last post in this command to delete the appointments originating from the deleted user in every mailbox whose Custom Attribute 14 is set to ResourceMB. I went ahead and entered this custom attribute for every conference room, projector, and video cart we have so that I can clean them all up with one command.

You can also use the –TargetMailbox parameter to redirect items to a separate mailbox instead of delete them in the event of a disaster. The full list of parameters for TargetMailbox is located here.

Quick note.  I ran into a scenario where the user’s account was already deleted, so when I would run the command, it didn’t do any clean up.  When I checked the appointment, I saw that the user had ‘No e-mail address exists for this person’ in the properties in Outlook.  Since this was the case, the command using the email address obviously didn’t work.  I replaced the email address with the displayed user name in the appointment and it worked like a champ.  The modified command looked something like this:

Get-Mailbox -Filter {CustomAttribute14 -eq ‘ResourceMB’} | Export-Mailbox -SenderKeywords “Lastname, Firstname” -IncludeFolders “\Calendar” –DeleteContent

Be sure to get the ‘Lastname, Firstname” value from what is displayed in the orphaned appointment.

Select and Clean Out Exchange 2007 Mailbox using a Custom Attribute

We were getting slim on storage on our Exchange server so I had to knock out some cleanup today. I saw that there were several service accounts with 40K messages or so apiece in them. Not sure how common these mailboxes are, but some are dumping grounds for NDRs, network/service alerts, or in our case, mail flow monitoring accounts. So, I composed this simple command to clean out the inbox of those service accounts. This script is for 2007, not 100% how different the script would be in 2010 since I know they made some significant changes to the 2010 Export-Mailbox command, but this worked like a dream in 2007:

Export-Mailbox -Identity ‘service-mailbox’ –DeleteContent

This quick script will delete all messages from the mailbox with no backup. Of course, you have to replace ‘service-mailbox’ with the alias of your service mailbox.

Now, I took it one step further. In order to repeat this process on a semi-regular basis, I added an ‘svc’ value to Custom Attribute 15. I then wrote this command to select these accounts and clean them out:

Get-mailbox -Filter { CustomAttribute15 -eq ‘svc’} | Export-Mailbox –DeleteContent

I personally ran the above command with a –WhatIf at the end of it to make sure I was going to be cleaning out the mailboxes I had intended to clean out.

I now have a command I can schedule to run monthly to keep these mailboxes under control.

Runas Batch File To Launch MMC as Domain Admin

So, I recently started with a new company that wisely implements User Account Control on the desktops, and follows the best practice of having one administration account for Domain Admins and a separate account for everyday use. I came from an environment where I was supporting several different domains so to build an MMC for my clients didn’t make much sense. Had I written this little batch file before, it would have made my onsite visits much easier. I am running this on Windows 7 SP1 x64. The batch file is quite simple, but I didn’t find anything with instructions on how to ‘make it all work’ so I thought I’d throw this blog out there.

Step 1: Check your services, and make sure the “Secondary Login” service is running and set to Automatic. If this service isn’t running, you can’t log in using runas.

Step 2: Create a folder on the C drive and name it MMC. If you are going to be visiting multiple clients, or if you are going to be administering multiple disjointed domains, add the “Everyone Full Control” permission to this folder. I’m not 100% sure if is important (and I honestly didn’t test it), but I would believe it would simplify things so that the batch file doesn’t have to get past the local permissions of your PC to also run on the domain your PC is a guest on. If you are running this on your own domain, or a domain your PC is a member of, then this isn’t as important.

Step 3: Create a new MMC with all of the Snap-Ins you like to use regularly and save it to the C:\ MMC folder. I added ADUAC, DNS, DHCP, ADS&S, RDC, Event Viewer, Services, and Computer Management. I’m sure I’ll add more later but those are the basics that I started with.

Step 4: Create a batch file in that folder with the following text where:

  • %domain% is the domain you’re logging in to.
  • %username% is the user name you’re logging in with.
  • %filename% is the name of the MMC file you created and saved in Step 3.

runas /user:%domain%\%username% “mmc C:\MMC\%filename%.msc”

For Example, if I were logging into with the user ID Matt and the MMC file I created was named Console, then the script would look like this:

 runas /user:company\Matt “mmc C:\MMC\console.msc”

I initially had problems with Windows 7 and received the error: 193: console.msc is not a valid win32 application, which is why I added the “mmc ” into the script. Not sure why Windows 7 had a problem associating MMC with msc in the batch file, but specifying mmc did the trick. I read that tip here.

Step 5: Save and close your batch file naming it something that makes sense to you.

Step 6: Copy a shortcut to your desktop (or other convenient location) and change the Icon if desired.

Step 7: Launch your batch file. Be sure to Right Click and select “Run As Administrator” if your PC has UAC turned on.

Step 8: After you launch the batch file, a cmd window will pop up and you will be prompted for a password. Enter the password for the user you defined in the batch file and you’re all set.

So, you can see the different applications of this batch file. If you’re a roaming admin, you can create a separate file for each client. In my case, we acquired a company not too long ago, so I will have one batch file (and likely a different msc defaulting to certain servers) for each of the domains for ease of administration.

Still working on the Exchange Management console.  The same script throws the same ‘invalid Win32 Application’ with our without the preceeding MMC part of the script.  I can Shift-Right Click, and ‘Run as different user’, but I’d rather not…..

Good luck, and happy administration!

Deauthorized DHCP Servers Still Listed

I’ve run into the situation several times in the past where you deauthorize a DHCP server/scope, but when you click on “Add Authorized” server in your DHCP MMC snap-in, it still lists the old servers. I’ve found the quickest and most efficient way to remove these servers is using ADSIedit.

  1. Click start, in the search box type MMC and hit enter.
  2. On the console screen that pops up, add ADSIEdit to your list of snap-ins.
  3. Right Click “ADSI Edit” and select “Connect to…” from the menu.
  4. Leave all defaults except the “Select a wekk known Name or Naming Context”. Hit the drop down arrow and select Configuration and then click OK:

  5. Drill down to CN=NetServices and highlight it:

  6. Double click on CH=DhcpRoot.

  7. Scroll down until you find the dhcpServers attribute. Double click on that attribute and remove the offending servers from the value field. Apply and close and you’re done!

Active Directory Health Checks

AD Health Checks

As a matter of course, I always start my troubleshooting of any funky network issues with a standard set of Active Directory health checks. This is the blog post I’ve used for a few years now: (

After doing this several hundred times, I finally got around to writing a batch file to run all of the checks in sequence. Below is the text for the script. Paste this into a .bat, create the ADLogs folder and then change the file location appropriately and you’ll be all set. Good Luck!


echo off

REM ###########################################

REM    AD Health Check batch file. This runs standard health

REM    checks in Active Directory and puts the results into

REM    the D:\ADLogs directory.

REM    Written by: Matt Richardson

REM    Last Update: 9/2/2011

REM    Reference: 06/03/2008 Blog post by MSMVP BrianM

REM ###########################################

echo The following AD Health Checks are now running: dcdiag, netdiag, dhcp, and repadmin. Your results can be found in D:\ADLogs.

title AD Health Check Now Running…..

REM The real work begins here

dcdiag /v >> d:\ADLogs\dcdiag.txt

netdiag.exe /v >> d:\adlogs\netdiag.txt

netsh dhcp show server >> d:\adlogs\dhcp.txt

repadmin /showreps >> d:\adlogs\showreps.txt

repadmin /replsum /errorsonly >> d:\adlogs\repadmin_err.txt

title AD Health Check Complete!

echo AD Health Check Complete!

timeout 10


UPDATE for Server 2008

I have updated the script to give a more complete look at the domain with the addition of the /c switch on the dcdiag command, and removed the netdiag command which has been essentially removed from 2008.

echo off

REM ###########################################

REM    AD Health Check batch file. This runs standard health

REM    checks in Active Directory and puts the results into

REM    the c:\ADLogs directory.

REM    Written by: Matt Richardson

REM    Last Update: 1/25/2012

REM    Reference: 06/03/2008 Blog post by MSMVP BrianM

REM ###########################################

echo The following AD Health Checks are now running: dcdiag, dhcp, and repadmin. Your results can be found in c:\ADLogs.

title AD Health Check Now Running…..

REM The real work begins here

dcdiag /c /v >> c:\ADLogs\dcdiag.txt

netsh dhcp show server >> c:\adlogs\dhcp.txt

repadmin /showreps >> c:\adlogs\showreps.txt

repadmin /replsum /errorsonly >> c:\adlogs\repadmin_err.txt

title AD Health Check Complete!

echo AD Health Check Complete!

timeout 10