Hey, Scripting Guy! Question

Hey, Scripting Guy! I have a file that has the name BackupFile-06122007.txt, where the 06122007 represents yesterday’s date (June 12, 2007). Each morning I would like to run a script that changes the name of that file so that it uses today’s date: BackupFile-06132007.txt. How can I do that?

-- GZ

SpacerHey, Scripting Guy! AnswerScript Center

Hey, GZ. You know, one thing you can count on is that the Scripting Guys will always be the same, no matter where they are or what they’re doing. For example, last week at TechEd 2007 Scripting Guys Jean Ross and Greg Stemp managed to get themselves caught in a torrential downpour while visiting Disney’s Animal Kingdom. Considering they had to walk for about half an hour or so before they could find a taxi to take them back to the hotel, they got completely and totally soaked.

Note. OK, so maybe they didn’t have to walk for half an hour; truth be told, the walk would have been considerably shorter had they not walked right past the exit and essentially circled the entire park before finding the way out. But, then again, if they were capable of doing a simple thing like following the signs that say Exit, well, they really wouldn’t be Scripting Guys, would they?

And while he didn’t say a word, we have no doubt that the taxi driver was thrilled to have two sopping wet Scripting Guys pile into the back of his previously-dry cab.

The very next day the Scripting Guys showed up at the TechEd 2007 attendee party, and rode Popeye and Bluto’s Bilge-Rat Barges at Universal Studio’s Island of Adventure theme park. As you might expect, they got completely and totally soaked.

Note. Here’s a handy travel tip. Theme parks can be expensive; there’s no two ways about that. However, with a little ingenuity you can experience many theme park rides in the comfort of your own home. For example, to recreate the experience of riding Popeye and Bluto’s you can do this: sit down in a chair, and use a makeshift seatbelt to strap yourself in. Then have someone dump 15 or 20 buckets of water over your head. That’s pretty much the whole ride right there.

And, yes, now that you mention it, the Scripting Guys did ride this ride several times. In a row.

After that somewhat damp experience what do you suppose Scripting Guy Greg Stemp did upon arriving back in Seattle? That’s right: he went to his son’s baseball game, a game played (at least until the umpires finally called it off) in a driving rainstorm. And needless to say, a game where he got completely and totally soaked.

Apparently it really is true: the more things change the more they stay the same.

Fortunately, that’s also true when it comes to answering scripting-related questions. Before the Scripting Guys left for TechEd they tried to answer a new question each and every day. And now that they’re back, well, like they say, the more things change, the more they stay the same:

strComputer = "."

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

strMonth = Month(Date - 1)

If Len(strMonth) = 1 Then
    strMonth = "0" & strMonth
End If

strDay = Day(Date - 1)

If Len(strDay) = 1 Then
    strDay = "0" & strDay
End If

strYear = Year(Date - 1)

strFileName = "C:\\Test\\BackupFile-" & strMonth & strDay & strYear  & ".txt"

Set colFiles = objWMIService.ExecQuery _
    ("Select * From CIM_DataFile Where Name = '" & strFileName & "'")

For Each objFile in colFiles

    strMonth = Month(Date)

    If Len(strMonth) = 1 Then
        strMonth = "0" & strMonth
    End If

    strDay = Day(Date)

    If Len(strDay) = 1 Then
        strDay = "0" & strDay
    End If

    strYear = Year(Date)

    strNewFileName = "C:\\Test\\BackupFile-" & strMonth & strDay & strYear  & ".txt"

    errResult = objFile.Rename(strNewFileName)
Next

Sorry; hopefully you can read the script code OK. Looks like we’re still dripping a little bit. And Greg’s hat may never be the same again.

But enough about all that. As you can see, even it first glance, this is a slightly-more complicated script than you might have expected. Why? Well, before we can rename a file we have to bind to that file using a script; in order to do that, we need to know the complete file path. And that’s a problem: after all, each day the file is going to have a different name. (For example, if today this is named BackupFile-06122007.txt, then tomorrow it will be named BackupFile-06132007.txt, and so on.) Thus we have to do two things here: figure out the current name of the file, and then rename it.

Sounds hard, doesn’t it? However, because GZ needs to run this script every single day this turns out to be surprisingly easy.

Let’s show you what we mean by that. Our script starts off by connecting to the WMI service on the local computer (although this script works equally well against a file stored on a remote computer). This is the point where we would typically bind to the file in question. So why don’t we do that now? That’s easy: we don’t know which file to bind to. Therefore, before we can do anything else we need to figure out the file path for our target file. And because part of that path (and part of the file name) consists of yesterday’s date, we run this block of code:

strMonth = Month(Date - 1)

If Len(strMonth) = 1 Then
    strMonth = "0" & strMonth
End If

strDay = Day(Date - 1)

If Len(strDay) = 1 Then
    strDay = "0" & strDay
End If

strYear = Year(Date - 1)

What are we doing here? Well, to begin with, we use the Month function to determine the month for yesterday’s date; that’s what the Date – 1 is for (the current date minus 1 day). The Month function is going to return an integer value representing the month; for example, the function returns 10 if the yesterday’s month fell in October, 12 if yesterday’s month fell in December, and 6 if yesterday’s month fell in June.

And yes, you’re right: we already have a problem, don’t we? Suppose we used this date in the file name: 1112007. So is that 1/11/2007, or is that 11/1/2007? Truthfully, there’s no way to tell. Therefore, we need to make sure that the months (and days) are listed as two-digit values, with leading zeroes used to pad the single-digit months. (In other words, modifying the month of June to be 06 rather than 6.)

Fortunately, that’s pretty easy to take care of: we just use the Len function to determine the number of characters in the month (technically, in the variable strMonth). If there’s only one character in the month we then use this block of code to add a leading 0, changing 6 to 06:

strMonth = "0" & strMonth

What if there are already two characters in the variable strMonth? Then we don’t do anything at all; we’re fine. And if there are three characters in the month? Then that means the Scripting Guys really need to stop taking their laptops on water rides like Popeye and Bluto. (It’s just so hard to tear yourself away from email, you know?)

We then repeat this process for the day, using the Day function to extract the day portion of yesterday’s date and, again, adding a leading zero if needed:

strDay = Day(Date - 1)

If Len(strDay) = 1 Then
    strDay = "0" & strDay
End If

Finally, we use the Year function to assign the year for yesterday’s date to a variable named strYear:

strYear = Year(Date - 1)

In this case there’s no need to add a leading zero because, by default, years are reported back as four-digit values.

After we have the individual pieces we can then construct yesterday’s date – and, in turn, the current file path – by using this line of code:

strFileName = "C:\\Test\\BackupFile-" & strMonth & strDay & strYear  & ".txt"

As you can see, this is a pretty straightforward equation: we’re just combining the file path and the first part of the file name (BackupFile-) with the variables representing the month, day, and year, tacking the .txt file extension on the end. The only tricky part here is that the \ is a reserved character in WMI; among other things, that means that this character (like all reserved characters) must be “escaped” before that character can be used in a WMI Where clause. So how do you escape a character in WMI? That’s easy: you just preface it with a \. If you’ve been sitting there wondering, “Why C:\\Test\\BackupFile-? Why not C:\Test\BackupFile-?” well, now you know.

After we’ve figured out the current name of our file we then use a regular old ExecQuery call to bind to the file, using the variable strFileName to represent the file path:

Set colFiles = objWMIService.ExecQuery _
    ("Select * From CIM_DataFile Where Name = '" & strFileName & "'")

Assuming all goes according to plan (and with the Scripting Guys everything always goes according to plan; we just have a tendency to make really bad plans) we should get back a collection (with the name colFiles) consisting of all the files with the designated file path. And because file paths must be unique on a computer that means we’ve located – and connected to – our target file.

That also means that we’re just about ready to rename the file. Before we can do that, though, we need to create a new name for our file. Fortunately we don’t have to put much thought into that: we already know that the file is going to be named C:\Test\BackupFile-insert current date here-.txt. With that in mind we go ahead and repeat the same process we just finished: we grab the month, day, and year, albeit this time for today’s date, not yesterday’s date. Once we have all that data we construct a new file name and store that value in the variable strNewFileName:

strNewFileName = "C:\\Test\\BackupFile-" & strMonth & strDay & strYear  & ".txt" 

Now all we need is one line of code and the Rename method and we can rename the file:

errResult = objFile.Rename(strNewFileName

And there you have it.

Incidentally, we realize that many of you were unable to make it to the Scripting Son’s baseball game, the one played in the torrential downpour. (But don’t worry: he’s got a good 50-60 games left this season.) If you’re interested in knowing what the game was like, here’s a handy hint: get in the car, drive for 50 miles, then sit down in a chair and have someone pour buckets of water over your head for the next two hours. And then get in the car and drive back home. That’s pretty much all there was to it.

Note. So are the Scripting Guys a little tired of spending all their time underwater? No, not really. After all, our careers have been underwater for years; we might as well join them.