Hey, Scripting Guy! Question

Hey, Scripting Guy! I have an unknown number of files in a folder. I need to rename them using this format: ABC_fx.inv, where x is an incremental number. How can I do that?

-- RN

SpacerHey, Scripting Guy! AnswerScript Center

Hey, RN. You know, one of the Scripting Guys once had an idea for a very different kind of restaurant. Would you walk into this restaurant, sit down at a table, and then order from the menu? No way! Instead, you’d walk in and pay a set price (say, $10) and you would never order from the menu. Instead, you’d spin a wheel, and whatever item the wheel landed on is what you’d get.

Now, admittedly, that could be bad: if the wheel lands on a grilled-cheese sandwich, well, then you just spent $10 on a grilled-cheese sandwich. But suppose the wheel lands on steak-and-lobster? Now you’ve gotten steak-and-lobster for just $10; that’s not a bad deal at all. Looking for a unique dining experience? Look no further.

So what does that have to do with incrementally renaming all the files in a folder? Nothing; we just wanted to mention the restaurant idea in case any venture capitalists happen to be reading this column. Guys, you know how to reach us.

You know, that’s a good idea: while we sit here and wait for the venture capital to start rolling in we might as well kill some time by answering RN’s question. OK, RN, here’s a script that will incrementally rename all the files in the folder C:\Data:

strComputer = "."

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

Set colFiles = objWMIService.ExecQuery _
    ("ASSOCIATORS OF {Win32_Directory.Name='C:\Data'} Where " _
        & "ResultClass = CIM_DataFile")

i = 1

For Each objFile in colFiles
    strNewName = "C:\Data\ABC_f" & i & ".inv"
    errResult = objFile.Rename(strNewName)
    i = i + 1
Next

And yes, we’d be happy to explain how this script works. (Note to potential investors: when’s the last time you heard about Emeril or Mario Batali taking the time to explain how a system administration script works?) As you can see, we start off by connecting to the WMI service on the local computer. Could we use this same script to rename files on a remote computer? Of course we could; all we have to do is assign the name of the remote computer to the variable strComputer. For example, this line of code causes the script to rename files on the remote computer atl-fs-01:

strComputer = "atl-fs-01"

Fine dining, scripts that connect to remote computers, and plenty of free parking. What more could you ask for?

After connecting to the WMI service we then use this line of code to retrieve a collection of all the files in the folder C:\Data:

Set colFiles = objWMIService.ExecQuery _
    ("ASSOCIATORS OF {Win32_Directory.Name='C:\Data'} Where " _
        & "ResultClass = CIM_DataFile")

We agree: it is a weird-looking line of code. But don’t worry too much about that. If you’d like to better understand how Associators Of queries work, then take a look at the WMI SDK. Otherwise, just be content with the knowledge that if you’d like to work with a different folder all you have to do here is replace C:\Data with the path to that folder. Want to work with D:\Accounting\Invoices? OK:

Set colFiles = objWMIService.ExecQuery _
    ("ASSOCIATORS OF {Win32_Directory.Name='D:\Accounting\Invoices'} Where " _
        & "ResultClass = CIM_DataFile")

As soon as we have a collection of all the files in the folder (and it doesn’t matter how many files there are, this query grabs each and every one) we’re ready to start renaming these babies. To do that, we first assign the value 1 to a counter variable named i:

i = 1

Why do we give this variable the value 1? Well, we want to incrementally name all the files in the folder, with the first file being file 1 (ABC_f1.inv), the second file being file 2, etc. Because we’re using i as a way keep track of which number needs to be assigned to which file we logically need to start off with i being equal to 1.

Note. Would Rachael Ray know that we should set up a counter variable named i, and that we should set the value of i to 1? Well, we’re not saying that she wouldn’t know to do that; we’re just pointing out that she doesn’t talk much about counter variables on her cooking show.

Seems kind of strange to us, too.

Our next step is to set up a For Each loop to loop through all the files in the collection (which, of course, corresponds quite nicely to all the files in the folder C:\Data). Inside that loop we execute these three lines of code:

strNewName = "C:\Data\ABC_f" & i & ".inv"
errResult = objFile.Rename(strNewName)
i = i + 1

In line 1 we’re constructing a new file name (or, to be a bit more accurate, a new file path). To do that we simply combine the following items:

C:\Data\ABC_f

The counter variable i (which, the first time through the loop, is equal to 1)

.inv

Add them altogether and you get this:

C:\Data\ABC_f + 1 + .inv = C:\Data\ABC_f1.inv

As it turns out, C:\Data\ABC_f1.inv is exactly the file path we need to use for the first file in the collection. And note that we do need to use the complete path when using WMI to rename files; the file name alone won’t do us any good.

Once we have the complete path renaming the file is as easy as calling the Rename method and passing this method the file path we just constructed:

errResult = objFile.Rename(strNewName)

So much for file 1. In order to rename file 2 in the collection we increment the value of i by 1 (meaning i is now equal to 2), then loop around and repeat this process with file 2. This continues until we have incrementally renamed each and every file in the folder.

A few quick notes here. First, by default files returned using a WMI query come back in alphabetical order. That means that the file that comes first alphabetically – for example, AAAA.txt – is going to be the first file to be renamed (and thus get the name ABC_f1.inv). Would it be possible to use a different order when it comes to renaming files, such as making the oldest file in the folder ABC_f1.inv? Yes, but not without adding additional code throughout the script. If that’s something someone out there needs to do, let us know.

Second, this script does what it’s supposed to do: it renames all the files in the folder. But suppose you already have a file named ABC_f1.inv. In a case like that, you might want to leave that file alone, and thus give the first file you do rename the moniker ABC_f2.inv. Will this script help you out in that situation? No. But, again, if a script like that would be useful to you just let us know.

Finally, you’re right: it’s highly unlikely that Martha Stewart would ever explain how you could write a script to handle any of these scenarios. But, in all fairness, that might not be Martha’s fault. One of the Scripting Guys actually wanted to ask Martha Stewart to make a guest appearance during the Scripting Week 2 webcasts, but he was told he couldn’t bring in outside guests. For all we know Martha Stewart could explain how to write a script; after all, she seems to know how to do pretty much everything else. She just never got the chance. Like we were told: no “guest stars” on TechNet webcasts.

Note. Of course, this Scripting Guy was also told that no one would go to a restaurant where they spun a wheel and then had to order whatever item the wheel pointed to. We’ll see, both about the new restaurant and about Martha Stewart.