BATCHman Uses PowerShell to Battle the Dread Madame CAT File

Summary: In today’s episode, intrepid BATCHman uses Windows PowerShell to battle the dreaded Madame CAT file—and the fur really flies.


Microsoft Scripting Guy Ed Wilson here. Windows PowerShell MVP Sean Kearney returns today for part 2 in his BATCHman series.

BATCHman and Cmdlet graphic


Deep in the most unforgiving lines of code, a new superhero emerges to bind the illogical, bring peace to the unfathomable binary things in the night, and seek justice where none can be found.

It’s your friend and mine, BATCHman!

….and his sidekick, Boy Blunder Cmdlet.


In Today’s Episode: BATCHman encounters the Dreaded Madame CAT file

Oh, no! The JobsBlog Team has been victimized by Madame CAT file! Madame CAT file loves to do nothing but rename files and place CAT all over the place. Today, she has attacked the folder structure of Microsoft Office leaving the JobsBlog Team helpless!

“Oh, how will we ever be able to review the resumes now? No Outlook! No Word! All of these resumes trapped! Resources untouched! Oh, where is BATCHman? Help us!”

Flying out of nowhere in a flurry of SMS packets and Gorilla Glass, and arriving with a classic “TADA” wav file from Windows 3.1, it’’s…

The truly dynamic (as opposed to static) BATCHman and Cmdlet!

“BATCHman! Thank goodness you’re here! We have millions of resumes to go through and Madame CAT file has rendered us helpless! Our copies of Microsoft Office are covered with nothing but the word “CAT.”

“Holy kitty litter, BATCHman!” bursts out Cmdlet. “What can we do?”

BATCHman quickly assesses the situation. There are two options he foresees.

“Well, Cmdlet, we could just do a System Restore to before Madame CAT file released her claws, but that will take time on all these computers. We need to restore the entire Jobs Blog to action quickly! If we aren’t careful, some fool might post over 8,000 resumes to the system and overload the team! It’s happened once before, and we just can’t take a chance!”

BATCHman thinks for a moment. “You know, I think we can take a shot at undoing this. Let’s see just how much damage that villain really did. I know Windows stores additional properties about certain key files, such as DLLs and EXEs, in the file itself.”

Cmdlet looks up. “Really? Zowie! How do we pull something like that up?”

BATCHman looks at an afffected file:

GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\CATWORDMEOW.EXE

“As we can see, Cmdlet, the file name has been completely tampered with, but if we run this against the Get-Member cmdlet, we can see there are additional properties available to us:

GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\CATWORDMEOW.EXE | GET-MEMBER

“I can see we have a property called VersionInfo. My scripting sense is tingling here. If we were to access this with a Select-Object cmdlet and see what it looks like…”

 Image of VersionInfo property

“Holy Harry Houdini, BATCHman! There’s the file name hidden in the Filename properties!”

“Yes, Boy Blunder, but we’ll have to dig a bit further. So let’s access the property directly to find the name of the property it can be referenced by. We could run the Get-Member cmdlet against it like this.”

(GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\CATWORDMEOW.EXE).VersionInfo | GET-MEMBER

“But let’s see if the information is easily accessible. Windows PowerShell has a tendency to try and make this easier.”

(GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\CATWORDMEOW.EXE).VersionInfo

Cmdlet just about dropped a process when he saw the results. “BATCHman! So if I were to type the Filename property…”

(GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\CATWORDMEOW.EXE).VersionInfo.Filename

His heart sank. “Oh, no! It’s the same! AIHGAIHGIAHGHIHAIGHIH!!!”

“Calm down, little Cmdlet. There are other properties. Sometimes just piping the output to the Format-List cmdlet will reveal them in a more useful manner. Remember, we’re looking at the default output in Windows PowerShell.”

(GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\CATWORDMEOW.EXE).VersionInfo | FORMAT-LIST

“So although you are correct in that the Filename shows the current file name, there is actually a property called OriginalFileName, which has been untouched by our Evildoer, and we can access it like this.”

(GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\CATWORDMEOW.EXE).VersionInfo.OriginalFileName

“BATCHman! Do you mean we could just check the properties of the .dll files and .exe files and possibly just rename them to the original? Even Madame CAT file made the name unrecognizable?”

Patting Cmdlet on the back he smiled. “That’s exactly what I mean!”

Then Cmdlet sighed. “BATCHman, that’s going to be a horribly complicated script! To pull up all those .dll and .exe files, analyze them, rename them, examine them…,” he rambled on.

“You forget, my young friend, that with Windows PowerShell, to pull such a list we simply need to specify the file extensions we want to include and recurse like this.”

GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\ –include *.exe, *.dll –recurse

“Yes I know! But how can we just rename them? To properly do that, we need the file path, the drive letter!” Cmdlet began to sob “WE’RE DOOOOOMED! DOOMED! DOOOOOOOOMED!”

“We could just run a Foreach, pull up the properties, and Rename the bad file name with itself like this, Cmdlet,” he stated calmly.

GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\ –include *.exe, *.dll –recurse | Foreach { Rename-item $_.Fullname –newname $_.OriginalFilename }

“B-b-but, BATCHman! There’s more than 200 files we could be affecting! What if we ruin them? What if we do something horrendously bad? What if your code destroys everything?”

“Funny you should mention the ‘what if.” I was thinking that very same thing. That’s why Windows PowerShell has a parameter called –whatif that is generally provided with any cmdlet that could make a change to the system. We just add it on like this and execute the code.”

GET-CHILDITEM C:\Program Files\Microsoft Office\Office14\ –include *.exe, *.dll –recurse | Foreach { Rename-item $_.Fullname –newname $_.OriginalFilename -whatif}

Cmdlet watched in amazement as each line was executed in the following fashion:

What if: Performing operation “Rename File” on Target “Item: C:\Program Files\Microsoft Office\Office14\MCATPUB.EXE Destination: C:\Program Files\Microsoft Office\Office14\MSPUB.EXE”.
What if: Performing operation “Rename File” on Target “Item: C:\Program Files\Microsoft Office\Office14\MSCAT32.EXE Destination: C:\Program Files\Microsoft Office\Office14\MSQRY32.EXE”.
What if: Performing operation “Rename File” on Target “Item: C:\Program Files\Microsoft Office\Office14\MSCATEDIT.DLL Destination: C:\Program Files\Microsoft Office\Office14\MSRTEDIT.DLL”.
What if: Performing operation “Rename File” on Target “Item: C:\Program Files\Microsoft Office\Office14\CATWORDMEOW.EXE Destination: C:\Program Files\Microsoft Office\Office14\WINWORD.EXE”.

“You see? With Windows PowerShell, we have a built-in way to test without breaking anything. As we can see, it appears this script should work. I’ll remove the –whatif parameter and execute as normal.”

Moments later, a system was recovered. All of the CAT litter was gone!

“Now quickly, Cmdlet! Take this USB key, run Windows PowerShell with administrative rights, and execute this code on each affected machine!”

In a matter of minutes the entire team was restored to productivity!

“Now keep in mind, Cmdlet, that this was a break/fix—a good one but a brake/fix nonetheless. We should speak to IT about having System Restore run on these machines later. But for the moment, we’re good!”

“Oh, BATCHman! How can we ever thank you?” burst out the JobsBlog Team.

“Easy! Always trust in Windows PowerShell and try not to let any more CATs in the office with local administrative access. BATCHman…AWAY!”


Thank you, Sean. Everyone come back tomorrow for part 3. Same BATCHtime, same BATCHchannel.

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

Ed Wilson, Microsoft Scripting Guy