March 27th, 2008

Hey, Scripting Guy! How Can I Change the Last-Accessed Date of a File to Match Its Last-Modified Date?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I change the last-accessed date for all the files in a folder? I want the last-accessed date to match the date and time that the file was last modified.

— GW

SpacerHey, Scripting Guy! AnswerScript Center

Hey, GW. Say, did you realize that yesterday was Opening Day for Major League Baseball? If you didn’t, well, don’t feel bad; even the Scripting Guy who writes this column forgot that yesterday was Opening Day. In fact, he didn’t remember anything at all about Opening Day until he got up Tuesday morning, turned on the TV, and saw that the Boston Red Sox were leading the Oakland A’s 6-5 in the bottom of the tenth.

Before you ask, no, the Scripting Guy who writes this column doesn’t get to sleep all day; instead, he – very grudgingly – gets up at 6:15 every morning. However, the game was being played, and was very nearly over, because of one of those curious decisions that only Major League Baseball can come up with. Baseball is considered America’s national pastime, and Opening Day is – along with the World Series – one of the cornerstones of the entire season. “So let’s see,” reasoned the folks who run Major League Baseball. “We have America’s national pastime, we have a game that all baseball fans are interested in watching – wait, I’ve got it: we’ll play the opening game of the season in Japan, and have that game take place in the middle of the night when most Major League Baseball fans are sound asleep!”

Note. If you ever wondered how baseball could end up with the designated hitter (albeit in only one of the two leagues); World Series games played in November; and an All-Star game that ends in a tie (!), well, now you know.

Oddly enough, however, it’s the Japanese baseball fans that the Scripting Guy who writes this column feels bad for. (And not just because they got stuck having to watch the Oakland A’s.) As most of you probably know, they already play baseball in Japan, and it’s actually a pretty cool experience: the fans in the outfield bleachers stand through the entire game; they sing songs; they do cheers; they shoot off fireworks; they bang drums. Oh, and they sell beer, too, although instead of having some fat guy walk around with a tray of plastic glasses they have girls walk around with kegs of beer strapped to their backs.

No, we’re serious. Here’s a picture the Scripting Guy who writes this column took of one such beer vendor:

Japanese Baseball

You’re trying to tell us that the Japanese have girls walking around with kegs of beer strapped to their backs and yet they need Major League Baseball? Major League Baseball, where even the cup holders on each and every seat have advertisements? Major League Baseball, where they actually tried to put advertisements on the bases, before public outcry caused them to beat a hasty retreat? Please.

In case you’re wondering, the Scripting Guy who writes this column speaks from experience: he’s actually been to a Japanese Pacific League game. A few years ago, when the Scripting Son was playing on an all-star team that toured the Tokyo area, the Scripting Guy who writes this column watched the Chiba Lotte Marines defeat the Orix Blue Wave (a team that has since merged with the Kintetsu Buffaloes.)

In fact, here’s his “Bobby Seat” ticket featuring a picture of manager Bobby Valentine:

Japanese Baseball

Good luck trying to find a Bobby Seat in the US!

If you, like the Scripting Guy who writes this column, missed Opening Day, well, that’s too bad: after all, there’s only one true Opening Day. And that’s doubly bad because many of you are probably already a bit distraught over the fact that VBScript provides no way to modify the last-accessed date of a file. You can use the FileSystemObject to retrieve the value of the last-accessed date, but there’s no way – no way that we know of, at least – to change that value.

Note. However, you can change the value of the last-modified date, if that helps. For more information, see our TechNet Magazine article Our Favorite Shell Games.

But don’t despair. Although there’s nothing we can do about Opening Day 2008 (well, not unless Scripting Guy Peter Costantini finishes his time machine), there is something we can do about changing the last-accessed date for all the files in a folder. As long as you’re willing to use Windows PowerShell (and there’s no reason why you shouldn’t be willing to use it) this little script should do the trick:

Get-ChildItem C:\Scripts | Where-Object {$_.PSIsContainer -eq $False} |
ForEach-Object {$_.LastAccessTime = $_.LastWriteTime}

As you can see, this is just a single line of PowerShell code. (Well, OK, it looks like two lines. But that’s because we had to break the line in order to get it to fit nicely on the page.) We start out in simple enough fashion, using the Get-ChildItem cmdlet to retrieve a collection of all the items in the folder C:\Scripts. That’s what this hunk of code is for:

Get-ChildItem C:\Scripts

As we noted a second ago, Get-ChildItem is going to return all of the items in the folder C:\Scripts; that includes subfolders as well as files. That’s fine, except that all we care about are files (and not just for the purposes of this script; the only things the Scripting Guys care about, period, are files). Because of that, we next take our collection and “pipe” it to the Where-Object cmdlet:

Where-Object {$_.PSIsContainer -eq $False}

Note. For those of you who haven’t worked with PowerShell, the $_ syntax represents the current object in the pipeline. That simply means that – what’s that? Oh, you say you don’t know what the pipeline is either? Then you should take a look at our article Piping and the Pipeline.

What we do next is ask Where-Object to filter the collection for us, retaining only those items where the PSIsContainer property is False ($False). As you might have guessed, if PSIsContainer is False then we’re dealing with a file; if PSIsContainer is True then we’re dealing with a folder (that is, with a container).

Finally, we take the filtered collection and pipe it to the ForEach-Object cmdlet:

ForEach-Object {$_.LastAccessTime = $_.LastWriteTime}

As the name implies, ForEach-Object is going to loop through each and every object in the filtered collection and then do something to each of those objects. What’s it going to do? That’s easy: it’s going to set the value of the object’s LastAccessTime property to the value of its LastWriteTime property. In other words, it’s going to change the last-accessed date to match the value of the last-modified date.

Which is all we ever wanted to do in the first place.

We should probably note that it is possible to use VBScript to go the opposite route: to change the last-modified date so it matches the last-accessed date. (Which might work for you, GW; after all, the net result is that the last-modified date and the last-accessed date end up being identical.) If it’s OK to go that route then this script should help:

Set objShell = CreateObject("Shell.Application")
Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFolder = objShell.NameSpace("C:\Scripts")
Set colItems = objFolder.Items

For Each objItem In colItems
    Set objFile = objFSO.GetFile(objItem.Path)
    dtmNewDate = objFile.DateLastAccessed
    objItem.ModifyDate  = dtmNewDate
Next

For more information, see our TechNet Magazine article.

As for the Major League Baseball season, here’s an interesting piece of trivia for you. Oakland and Boston will play two official games in Japan, then return home and resume spring training; Boston, for example, will come back and play three exhibition games against the Dodgers (boo!) before continuing the regular season on April 1st against Oakland. Cool, huh? Maybe next year the Seattle Mariners and the Kansas City Royals will go to Australia in November, play the first two games of the 2009 season, then come back to the US and wait for spring training to start in February.

And yes, we realize that games played in November could conflict with the 2008 World Series. But that’s OK; most likely the Mariners and the Royals won’t have to worry about any such conflict.

Note. Especially the Mariners: their two big-money, big-name free agent pitchers – Eric Bedard and Carlos Silva – both have spring training earned-run averages above 9.20.

Oh, well. Football season can’t be far off, right?

Author

0 comments

Discussion are closed.