Hey, Scripting Guy! How Can I Find Folders Whose Name Fits a Specified Pattern?

ScriptingGuy1

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have a bunch of folders that had names like this: BAD_20080411; in other words, the characters BAD_ followed by the date. These folders can be on any drive on my computer. How can I write a script that will locate all these folders for me?
— NS

SpacerHey, Scripting Guy! AnswerScript Center

Hey, NS. Did you hear about the construction worker who attempted to place a curse on the New York Yankees by burying a David Ortiz Boston Red Sox jersey under two-and-a-half feet of concrete in the new Yankee Stadium (currently under construction)? Your first thought upon hearing that might have been, “So what?” especially when you consider the fact that David Ortiz is currently batting .104, with just one home run and three RBIs. Nevertheless, the Yankees didn’t find it so amusing, and spent an estimated $50,000 digging up the jersey.

To their credit, the Yankees plan to auction off the jersey and donate the proceeds to the Jimmy Fund, the Red Sox’ favorite charity. Of course, the Yankees also plan to talk to the district attorney’s office about the possibility of filing criminal charges against the construction worker who planted the jersey. As far as we know, the Yankees want to have the construction worker weighted down with stones and then tossed into the Hudson River. If he sinks and drowns, well, then the team will concede that no crime was committed after all. If the construction worker floats, however, he’ll be hauled out and burned at the stake for being a witch.

Which, interestingly enough, is how the Yankees got rid of their last two left fielders.

We mention this not to poke fun at the Yankees; after all, when the Scripting Guy who writes this column was growing up his favorite player was Yankee centerfielder Bobby Murcer. Instead we consider this a public service: if you’ve been having a streak of bad luck lately the Scripting Guys strongly recommend that you dig up your entire backyard. Let’s face it: if there’s a David Ortiz jersey buried in Yankee Stadium there could be a David Ortiz jersey buried just about anywhere.

Baseball Trivia. David Ortiz was once in the Seattle Mariners organization; in fact, in 1996 he hit .322 with 18 home runs and 93 RBIS for the Wisconsin Timber Rattlers, a Mariners farm team. As a reward for this outstanding season Ortiz was traded to the Minnesota Twins for Dave Hollins. Hollins appeared in just 28 games for the Mariners and then signed a free agent contract with the Angels. In the meantime, Ortiz has had 263 home runs and 883 RBIs for the Red Sox, who’ve also won two World Series titles during his time with the team.

Incidentally, that has nothing to do with being cursed: the Mariners are always making deals like that.

Admittedly, digging up your backyard might seem like a pretty drastic measure, especially if you don’t find a David Ortiz jersey buried there. Alternatively, you can break a curse using this method, an approach we copied from an Internet newsgroup post:

Create a small circle of black salt, with Lavender incense burning to the left and the right of the Circle. Focus clearly on the intent that you want [to be rid of the curse]. A silvery ball should appear after 15 minutes. With your mind, push the ball towards [the person who cursed you], and within a week that should help out with your problem.

Personally I would use a simple Mind Spell to remedy it, but this method will be just as effective.

In other words, either approach – a circle of black salt or a simple Mind Spell – should do the trick. Or, you could also do what the Scripting Guys do any time they need to break a curse. (Which is more often that you might think, at least for people who work at Microsoft.) Any time someone places a curse on us we simply run a script that can locate all the folders on a computer whose folder name includes the characters BAD_ followed by a date:

Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Global = True   
objRegEx.IgnoreCase = True
objRegEx.Pattern = "^bad_\d{8}"
strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colFolders = objWMIService.ExecQuery("Select * From Win32_Directory")
For Each objFolder in colFolders
    strFolder = objFolder.FileName
    Set colMatches = objRegEx.Execute(strFolder)
    If colMatches.Count > 0 Then
        Wscript.Echo objFolder.Name
    End If
Next

Note. Will running this script really break a curse? Let’s put it this way: Jean and Greg are both still Scripting Guys, aren’t they?

Our script starts out by creating an instance of the VBScript.RegExp object, the object that enables us to use regular expressions within a VBScript script. (Does that mean we’re going to use regular expressions in this script? You bet it does.) After we create the regular expressions object we set both the Global and IgnoreCase properties to True. That ensures that our script will do two things: 1) find all instances of the target text; and, 2) do a case-insensitive search for that target text. (In other words, the script will find folders starting with BAD_, with bad_, etc.)

Speaking of the target text, we use the following line of code to define the Pattern we’re looking for:

objRegEx.Pattern = "^bad_\d{8}"

As far as regular expressions go, this one is actually pretty straightforward. The syntax ^bad_ simply states that we are looking for the characters bad_ at the beginning of the folder name. (The caret symbol – ^ – matches items at the beginning of a string.) The construction \d{8} states that the characters bad_ must then be followed by 8 consecutive digits (any of the numbers 0 through 9). The following folder name matches our pattern:

Bad_20080411

However, this folder name does not match the pattern:

Bad_1234567

Why not? You got it: because the characters bad_ are followed by only 7 digits, not the required 8. This folder name won’t result in a match, either:

Test_bad_20080411

Why not? Right again: because bad_20080411 does not appear at the beginning of the name.

Note. We’re glad to hear that the curse placed on you hasn’t affected your ability to decipher regular expressions.

After configuring the regular expressions object we then connect to the WMI service on the local computer. And yes, you can run this script against a remote computer; to do that, simply assign the name of the remote machine to the variable strComputer:

strComputer = "atl-fs-001"

That should work just fine, assuming that there isn’t a curse on the remote computer.

Note. How could you even put a curse on a remote computer? Beats us; maybe by installing Linux on it?

Hey, just kidding.

Once we’re connected to the WMI service we can use this line of code to retrieve a collection of all the folders found on that computer:

Set colFolders = objWMIService.ExecQuery("Select * From Win32_Directory")

And yes, you’re right: this script could take a minute (maybe even more) to complete. But that’s probably not a sign that you’ve been cursed; most likely it’s because you have a large hard drive (or hard drives), and that you have a whole bunch of folders that need to be retrieved.

Now, in an ideal world we’d be able to use regular expressions right in our WMI query; that would enable us to retrieve only the folders of interest, without having to return the collection of all the folders on the computer. However, considering the fact that the Scripting Editor is still on staff, this is far from a perfect world. (Hey, just kidding, Scripting Editor; you know exactly how much we like you!) Because of that, our only recourse is to return a collection of all the folders and then look at each folder name individually, trying to determine whether the name meets the specified pattern.

With that in mind the next thing we do is set up a For Each loop designed to walk through all the folders in our folder collection. Inside that loop, we grab the value of the FileName property and store it in a variable named strFolder:

strFolder = objFolder.FileName

And yes, we know: FolderName would be a better name for this property, wouldn’t it? But, like we said, this is not an ideal world we’re living in. After all, in an ideal world Baseball Tonight would be on more than just twice each night.

Once we have the folder name in tow we can use the Execute method to run a regular expressions search against that name:

Set colMatches = objRegEx.Execute(strFolder)

If the target text can be found in the folder name then all the instances of that target text will be stored in a collection we named colMatches. How do we know if a given folder name matches the specified Pattern? That’s easy; we just check to see if the number of items in colMatches (the collection’s Count property) is greater than 0:

If colMatches.Count > 0 Then

If the Count is greater than 0 then we’ve found one of the folders we were looking for; in turn, we echo back the folder path (that is, the value of the Name property):

Wscript.Echo objFolder.Name

And then, either way, it’s back to the top of the loop, where we repeat the process with the next folder in the collection. When all is said and done, we should see information similar to the following onscreen:

d:\bad_20080411
d:\scripts\bad_20080412
e:\bad_20080413

Etc., etc.

Incidentally, David Ortiz is lucky it’s just his jersey that was buried under two-and-half-feet of concrete. During the Dark Ages it was believed that – in order to keep the river peaceful and under control – any new bridge built over that river had to include a body entombed within the bridge. We’re not sure whether that really did any good or not, but when the Scripting Guys world headquarters was being built we decided not to take any chances. Ever wonder why you haven’t heard much from Scripting Guy Peter Costantini lately? Well, now you know why.

See you all tomorrow.

0 comments

Discussion is closed.

Feedback usabilla icon