Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I locate all the instances of a particular file (like budget.xls) on a computer?

-- MN

SpacerHey, Scripting Guy! AnswerTechNet Script Center

Hey, MN. Did you know that former heavyweight boxing champion George Foreman has 10 children, 5 sons and 5 daughters? It’s true. But that’s not the best part; the best part is that all 5 of his sons are named George Edward Foreman. (And, just for good measure, one of his daughters is named Georgette.) Apparently that’s the sort of thing that can happen when you get hit in the head over and over again.

Of course, at least George (the original George) can use boxing as an excuse. By contrast, the Scripting Guy who writes this column also tends to use the same name over and over again, and he’s never been hit in the head. (Though many people have been tempted to do so.) For example, when he tackled this question he used Test.vbs as the file name to look for. The end result: he found 36 instances of Test.vbs, including:

c:\scripts\test.vbs
d:\itunes\test.vbs
d:\keep these\101 things\test.vbs
d:\keep these\2003 stuff\test.vbs
d:\keep these\adsi security\backup\test.vbs
d:\keep these\adsi security\test.vbs
d:\keep these\agent\test.vbs
d:\keep these\database webcast\test.vbs
d:\keep these\hta helpomatic\test.vbs
d:\keep these\miscellaneous\scripting guide\wmi presentation\test.vbs
d:\keep these\miscellaneous\test.vbs

Etc., etc., etc.

Note. Yes, it is a good thing that the Scripting Son is an only child.

In other words, at least some of us are very familiar with the concept (problem?) of having multiple files with the same name, all of these files scattered every-which-way on a computer. We won’t spend any time debating whether that’s a good thing or a bad thing (primarily because that’s a debate we can’t imagine winning). Instead, we’ll spend our time talking about the following script:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colFiles = objWMIService.ExecQuery _
    ("Select * From CIM_DataFile Where FileName = 'test' and Extension = 'vbs'")

For Each objFile in colFiles
    Wscript.Echo objFile.Name
Next

We hope you weren’t expecting a really complicated script here. For one thing, we don’t need a very complicated script; this is actually a pretty easy problem to solve. For another, remember that this Scripting Guy has given 36 different files the name Test.vbs. As you might expect, “complicated” isn’t a word he’s too terribly familiar with.

The script starts out by connecting to the WMI service on the local computer. Could we perform this same search on a remote computer? You bet we could; just assign the name of that computer to the variable strComputer:

strComputer = "atl-fs-01"

After connecting to the WMI service we then issue the following query:

Set colFiles = objWMIService.ExecQuery _
    ("Select * From CIM_DataFile Where FileName = 'test' and Extension = 'vbs'")

As you can see, we’re querying the CIM_DataFile class, which just happens to be the WMI class responsible for managing all the files on a computer. Of course, we aren’t interested in all the files on the computer, just those named Test.vbs. That’s why we tack on a Where clause that includes two stipulations:

All the files returned by the query must have a FileName equal to test; the FileName property is simply the name of the file minus the file extension. That’s an important consideration: many people who work with the CIM_DataFile class assume that the FileName is the “complete” file name (e.g., Test.vbs). It’s not. And don’t use the Name property in your query, either. We’ll explain what the Name property is for in just a minute.

All the files returned by the query must have an Extension equal to vbs. Again, be careful here: without thinking most people include the period when specifying the file extension (e.g., .vbs). Don’t do that.

Note. OK, don’t do that unless it doesn’t matter to you whether or not your query returns the expected information. If you’re running the script just for the pure joy of running a script, well, feel free to specify any file extension you want. But if you’d really like the script the find all instances of Test.vbs, leave out the period.

You’re right: CIM_DataFile can be a little tricky to work with, can’t it? About all we can say is that you should always wear gloves and safety goggles before using CIM_DataFile in a script. Oh, and check out the Microsoft Windows 2000 Scripting Guide if you need information about what the various properties really mean.

After our query finishes executing (a process that could take a minute or two, depending on the size of your disk drives and on the number of files stored on those drives) we set up a For Each loop to walk through the items in the collection, echoing back the Name of each file:

For Each objFile in colFiles
    Wscript.Echo objFile.Name
Next

And, yes, it probably would have been better if this property was called Path rather than Name; that’s because the Name really is the full path to the file (e.g., c:\scripts\test.vbs). But with CIM_DataFile, you need to expect the unexpected.

There you go, MN; that should help you track down all the files named Test.vbs. And if you’re looking for all the people in the world named George, we’d recommend starting at George Foreman’s house. You ought to be able to get at least half of them right there.