BATCHman Uses PowerShell to Battle the Evil Mr. Freeze-Process

BATCHman Uses PowerShell to Battle the Evil Mr. Freeze-Process

  • Comments 5
  • Likes

Summary: A new superhero uses Windows PowerShell for good. He is BATCHman, and today he battles Mr. Freeze-Process.

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! I know there are the Scripting Guy and Dr. Scripto, but are there any real scripting superheroes?

—SH

 

Hey, Scripting Guy! AnswerHello SH,

Microsoft Scripting Guy Ed Wilson here. Today is Episode 1 of a multipart BATCHman series written by Windows PowerShell MVP Sean Kearney. Read his other posts.

BATCHman and Cmdlet graphic

 

The one superhero to whom all others pale in comparison is faster than that so-called Flash guy with his efficiency of code and able to leap past unbelievable expectations of clients (more than SomewhatSuper Guy). He has the endurance of an all-night developer trapped in a last-minute bug fix and the strength of an IT pro standing in an overheating datacenter.

It’s your friend and mine: BATCHman!

…and his Boy Blunder Cmdlet.

 

In Today’s Episode, BATCHman Encounters Mr. Freeze-Process!

We find today the evil villain Mr. Freeze-Process—once a harmless data entry clerk known as VIC Twennie, who’s mind was so twisted he tried translating Hollerith cards to English—hovering over his victim, philanthropist Bill Gates.

”Buah ha ha ha haaa! I have you now! Your entire laptop held prisoner by my constantly spawning processes! A screen flooded in Notepad! A-ha! You will never get that email out to the world now with that newly discovered cure! Now quickly sign! Sign! Sign your autograph on every sheet of paper on this skid! I will make billions selling it on online auction sites!”

Mr. Gates looks to the ground sullenly. “Oh, if only BATCHman were here to save me from this diabolic and bad-acting villain!”

***Meanwhile back in the BATCHcave!***

“Cmdlet, my scripting sense is tingly! I sense, I sense trouble! Quickly! To the WinMobile!”

***Moments later with minimal explanation or plot! ***

“Oh, thank goodness you’re here, BATCHman! The Evil Mr. Freeze-Process has tied up my laptop with an application that constantly launches copies of Notepad. My CPU is pegged and I need to get a truly important email message out!”

BATCHman disposes his faithful sidekick to keep Mr. Freeze-Process busy by interviewing him for the fake Villain of the Year Award. Quickly he assesses the problem. There is a parent process spawning multiple copies of Notepad. “This is a job for Windows PowerShell!” he blurts dramatically.

“First, we must kill off most of these applications. Using Windows PowerShell, I can run the Get-Process cmdlet to find all the copies of it. I will store those results in a variable so that I don’t fill up the screen.”

$BADPROCESSES=GET-PROCESS NOTEPAD

“Now I can use the Stop-Process cmdlet. But rather than trying to stop them one at a time, I can just pipe the entire list in!”

$BADPROCESSES | STOP-PROCESS

By this time the Boy Blunder has returned, having bored Mr. Freeze-Process to sleep.

“Holy echo, BATCHman! They’re still appearing!” True enough, the Boy Blunder was right! Notepad kept appearing! “Zoinks! I almost forgot about the parent process! What a diabolic villain!”

Quickly, our hero thinks to himself. “I must find the newest process that launched just before all these child processes! *SNAP* Of course!”

BATCHman runs Get-Member against Get-Process:

GET-PROCESS | GET-MEMBER

He finds there is a property called Starttime.

“I shall run Get-Process, and not show any Notepad in the list. Then I shall run the output through Sort-Object based on the Starttime to put the most recent ones near the top. Odds are that Mr. Freeze-Process’ application is one of the last ones launched!”

GET-PROCESS | Where { $_.Name –ne ‘NOTEPAD’} | Sort-object Starttime

But a problem appears in the output! “Holy unclear answers, BATCHman! Look!” bursts out Cmdlet.

Image of issue in output

The BATCHman, never fazed, realizes not all processes such as system processes can have their properties read by the user. We can have this ignored in the output to make it clearer to read by adjusting the ErrorAction value in the line:

GET-PROCESS | Where { $_.Name –ne ‘NOTEPAD’} | Sort-object Starttime –erroraction ‘SilentlyContinue’

“Much better!” exclaims BATCHman, “but I really only need the most recent processes.”

“BATCHman,” Cmdlet pokes in, “could we run all of this through Select-Object and just take the top 3? We should have an easier time spotting parent applications launching all these vile Notepads!”

“Of course, Boy Blunder! Excellent work! We’ll use Select-Object and show the last 3 items in the process list!”

GET-PROCESS | Where { $_.Name –ne ‘NOTEPAD’} | Sort-Object Starttime –erroraction ‘SilentlyContinue’ | Select-Object –Last 3

Image of output of last three items in process list

“Now, Cmdlet, let’s strike that parent process! Taste BATCH Justice, EvilDoerProgram!”

GET-PROCESS EvilDoerProgram | STOP-PROCESS –force

“Let’s crush those remaining Notepad applications once more to get Mr. Gates back to his ability to save the world!”

GET-PROCESS NOTEPAD | STOP-PROCESS –force

In moments, the screen quiets down and the laptop returns to normal. Mr. Gates quickly clicks Send.

“Holy vanishing process, BATCHman! It appears the villain has run off!” screams Cmdlet.

“As evildoers always will, Cmdlet.” smiles BATCHman.

“Thank you BATCHman! How can I ever thank you?”

“Just keep doing what you do best, saving the world.”

BATCHman shakes Mr. Gates’s hand and is about to step onto the WinMobile when Cmdlet starts tugging on his cape.

“Yes, Cmdlet?”

“…pssst…pssst……psssst”

“Ah, I see. Mr. Gates, Cmdlet would like to get your autograph.”

“Why sure! There’s about five hundred in that pile over there.” Mr. Gates points at the former skid of paper provided by the Evil Mr. Freeze-Process

They all laugh as Cmdlet quickly executes his newly written advanced function GET-AUTOGRAPH | OUT-SAFE.

 

Thanks, Sean! Join us tomorrow for part 2 of the amazing adventures of BATCHman. Same BATCHtime, Same BATCHchannel.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

 

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Very nice. I love a good narrative! Good stuff, Sean :)

  • Really nice! Looking forward for the Next part!

  • Nice article.  Another option for trying to identify the parent process that may be a little more reliable than start time would be to use WMI's win32_process ParentProcessID.

    # To list the process IDs

    gwmi win32_process | ?  {$_.Name -eq "notepad.exe"} |select-object ParentProcessID | sort-object ParentProcessID |Get-Unique -asString

    # To actually stop the parent process

    gwmi win32_process | ?  {$_.Name -eq "notepad.exe"} |select-object ParentProcessID | sort-object ParentProcessID |Get-Unique -asString | foreach {stop-process -id $_.ParentProcessID}

  • hey Sean!

    All I can say: the long awaited Sean is back! ... saver of the universe!!

    or in PS:

    $heyScriptingGuyBlogs | %{if (blog($author) -eq 'Sean Kearney') {Start-Smiling}}

    Klaus.

  • correction:

    $heyScriptingGuyBlogs | %{if (author($_) -eq 'Sean Kearney') {Start-Smiling}}