Hey, Scripting Guy! How Can I Kill Processes?

Hey, Scripting Guy! It seems that every single piece of software I install adds a stub application that starts automatically. I know software makers do not do it out of maliciousness, but good grief these people act as if theirs is the most important software on my computer. In the old days, it was pretty easy. I’d go to the Startup folder and delete their icon. Now they start hiding their stuff in 25 different places in the registry. When people started finding their software in those locations, these software makers began masquerading as services with obscure names. It is enough to make a person remove patches of their own hair. Can you provide a low-stress, low-hair-loss way of controlling these offending applications?

- JB

Hi JB,

I can definitely sympathize with follicly challenged individuals, and do not wish to do anything that would cause you to remove more of the precious stuff. If you take a look at the script below, you will see that we read a text file that has a list of processes we wish to kill. We total the memory being consumed by the processes and ask if you, the user, wish to terminate them. For a similar VBScript, you can refer to this Dr. Scripto article. For more information about WMI, you may want to look at the WMI Secrets page or check out the Microsoft Press book, Microsoft Windows Scripting with WMI: Self-Paced Learning Guide. Here's the script:

The script uses a text file for input. Working with text files in VBScript is covered here. The first thing it does is initialize two variables. The first variable, $mem, is used to hold the amount of memory that will be saved by deleting the processes. The second variable, $procFile, is used to hold the path to the text file with the processes to kill:

$mem = 0
$procFile = "c:\FSO\annoyingProcesses.txt"

The text file is simply a list of process names:

Next it is time to read the text file and retrieve the process information for each of the processes. This can be done on a single line. The trick is that the Get-Process cmdlet will accept an array of process names for the –name parameter. To provide this array of process names, we use the Get-Content cmdlet and have it read the content from the file. Because we have the Get-Content cmdlet in parentheses, this forces it to be read first. The –ErrorAction continue is the same as placing On Error Resume Next in a script. It causes error messages to be ignored. After we have the process information for each of the processes, we pipeline the results to the next command. This line of code is seen here:

Get-Process -name (Get-Content $procFile) -ErrorAction continue |

Because we have a stream of process information, we want to work with each process individually. To do this, we use the Foreach-Object cmdlet. We wish to tally up the WorkingSet property of each of the processes. To do this, we use the $_ variable, which refers to the individual process object that is currently residing on the pipeline. We then query the WorkingSet value and add it to the current total of $mem. The += construction is the same as saying $mem = $mem + $_.WorkingSet. This line of code is seen here:

Foreach-Object { $mem += $_.WorkingSet }

The next line of code is used to print out the amount of memory that is being consumed. {0:N2} is a .NET framework format specifier that says we want to display numbers with two decimal places. The strange thing is that it appears in front of the –f instead of behind it. 1MB is called an administrative constant, and it is used to convert bytes to megabytes:

"{0:N2}"-f ($mem/1MB) +" meg of ram is being consumed by $procFile Processes"

Here is how memory being consumed is displayed:

It is now time to show a prompt, so we can ensure the user intended to stop all the processes. To do this, we use the Read-Host cmdlet. This code is shown here (the prompt itself can be seen in the previous image):

Now we need to evaluate the user’s response. To do this, we use the switch statement, which is similar to the Select case command from VBScript. The switch is used to determine what was handed to the Read-Host cmdlet. This value was stored in the $rtnPrompt variable. If it is equal to y, we print in green the processes that will be deleted, and then we call the Stop-Process cmdlet to stop each process. If the variable is equal to n, the message is printed in yellow to say that nothing will be stopped. If an invalid response is typed, the message is displayed in red that a y or n response was expected: