Hey, Scripting Guy! I need to check the size of a folder once every hour; if the folder has exceeded a specified size, I then need to delete the oldest file in that folder. How can I do that?
— JC
Hey, JC. You know, a lot of you are thinking, “Gee, I wonder what was the very best, very coolest thing that the Scripting Guy who writes that column saw on his recent trip to Italy?” As it turns out, that’s an easy question to answer: the very best, very coolest thing that the Scripting Guy who writes this column saw on his recent trip to Italy was housed at the Vatican Museum and – What’s that? The Sistine Chapel? Oh, is that at the Vatican? Well, what do you know? No, the – the Raphael Rooms? Sorry; never heard of them. At any rate, without a doubt the very best, very coolest thing the Scripting Guy who writes this column saw on his recent tip to Italy was housed at the Vatican Museum: a Pepsi-Cola!
You heard right: a Pepsi-Cola. The Scripting Guy who writes this column had been to Europe a couple times prior to his recent vacation, and never once had he even seen a Pepsi, let alone have the opportunity to drink one. But after completing their tour of the Museum the Scripting Family stopped off at the Museum cafeteria to get something to drink. And there it was: a can of Pepsi.
Needless to say, it was a profoundly moving experience, at least for a Scripting Guy who doesn’t really like Coca-Cola all that much.
Scripting Dad and Scripting Son note. As we mentioned, the family stopped off in the cafeteria just to get something to drink. Eat lunch there? Oh, please, not in a museum cafeteria. But then, just as the Scripting Dad and Scripting Son were reaching for their drinks, a cafeteria worker came by and plopped down a huge tub of pasta, pasta completely smothered with broiled cheese. For some reason, eating lunch at a museum cafeteria no longer seemed like such a bad idea after all. |
Of course, it goes without saying that drinking a Pepsi, in Europe, mind you, is an experience that will never be topped. So then what was the second-best and second-coolest thing the Scripting Guy who writes this column saw in Italy? That would have to be this vintage Italian script (made by artisans using the same materials and techniques Italian scripters have used for hundreds of years), a script that can check to see if a folder has exceeded a specified size and, if it has, delete the oldest file in that folder:
strOldestFile = “” dtmOldestDate = NowSet objFSO = CreateObject(“Scripting.FileSystemObject”) Set objFolder = objFSO.GetFolder(“C:\Scripts”)
intFolderSize = Int((objFolder.Size / 1024) / 1024)
If intFolderSize >= 25 Then Set colFiles = objFolder.Files
For Each objFile in colFiles strFile = objFile.Path dtmFileDate = objFile.DateCreated If dtmFileDate < dtmOldestDate Then dtmOldestDate = dtmFileDate strOldestFile = strFile End If Next
objFSO.DeleteFile(strOldestFile) End If
A couple quick notes before we begin. First, this script is designed to run only on the local computer. Why? Well, to run against a remote computer, the obvious technology of choice would be WMI. Unfortunately, though, there’s a bug in WMI’s Win32_Directory class: any time you retrieve the size of a folder the size comes back as 0 bytes. (If only we all had bathroom scales that worked in similar fashion!) That makes WMI a somewhat less-than-ideal technology for any task involving folder sizes. Could we perform this task remotely, even if that involves using a work-around or two? Yes we can, and that’s something we’ll take up in a future column, if anyone’s interested.
Second, this script is designed to run once and then stop. But wait, you say, didn’t JC need the script to check the folder size every hour? That’s correct. However, rather than add in code that pauses the script for an hour we recommend that you set up a scheduled task and have that task run the script once an hour. That’s a much better, much easier, and much more foolproof approach to getting a script to run once every hour.
Note. Why foolproof? Well, suppose something happens and the script process terminates (e.g., the command window in which the script is running is closed). In that case, you’ve lost your ability to monitor the folder, at least until you restart the script. With a scheduled task, you don’t ever have to worry about things like processes terminating prematurely and needing to be restarted. |
OK, so much for all that; let’s see if we can figure out how the script actually works. To begin with, we assign values to a pair of variables, strOldestFile and dtmOldestDate:
strOldestFile = “” dtmOldestDate = Now
We’re going to use the variable strOldestFile to keep track of the path to the oldest file in the folder C:\Scripts. Of course, at the beginning of the script we don’t know the path to the oldest file in the folder, so we simply assign this variable an empty string (“”).
Now, how are we going to determine which file is the oldest file in the folder? Well, we could figure that out by using some sort of complicated WMI query and sorting algorithm. However, we opted to do something a little easier: we’re simply going to assign a beginning value to the variable dtmOldestDate (in this case, that value being the current date and time, something we can calculate by using the VBScript Now function). After that, we’ll just loop through the collection of files found in the folder C:\Scripts. For each file, we’ll check to see if the file creation date is older than the value stored in dtmOldestDate. If it is, then we’ll assign the file path of that file to strOldestFile and the file creation date to dtmOldestDate. If it isn’t, well, then we’ll simply move on and repeat the process with the next file in the collection.
But more on that in a minute.
After initializing our variables we create an instance of the Scripting.FileSystemObject, then use the GetFolder method to bind us to the folder C:\Scripts; that’s what we do with this block of code:
Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objFolder = objFSO.GetFolder(“C:\Scripts”)
Once we’ve created an object reference (objFolder) to C:\Scripts we then use this line of code to store the size of that folder in the variable intFolderSize:
intFolderSize = Int((objFolder.Size / 1024) / 1024)
You know, you’re right: that is a somewhat-complicated looking bit of code, isn’t it? And, to be honest, there’s no need for it to be that complicated; instead, we could have simply assigned the value of the Size property to the variable intFolderSize, like so:
intFolderSize = objFolder.Size
So then why didn’t we just do that? Well, as it turns out, folder sizes are returned in bytes; that means a 25-megabyte folder will have a size equal to this:
26214400
There’s nothing wrong with that, but very few people (or, at least, very few Scripting Guys) can glance at the number 26214400 and immediately think, “Oh, 25 megabytes, eh?” Therefore, we did a little bit of math: we took the value of the Size property and divided it by 1024, giving us the size in kilobytes. We then took that value and divided it by 1024 once more, thus giving us a size (e.g., 25.1637182137) in megabytes. Finally, and because we really don’t care about the .1637182137, we used the Int function to strip off the decimal places.
The net result? We end up assigning a nice, clean value (25) to the variable intFolderSize. Because, as we all know, cleanliness is next to godliness.
Scripting Guys trivia. Contrary to popular belief, the phrase “Cleanliness is next to godliness” does not appear in the Bible. Instead, the quote comes from a sermon by John Wesley, founder of the Methodist church: “Let it be observed, that slovenliness is no part of religion; that neither this, nor any text of Scripture, condemns neatness of apparel. Certainly this is a duty, not a sin. Cleanliness is, indeed, next to godliness.” If that information doesn’t win you a bunch of bar room bets, well, you’re obviously hanging out in the wrong bar rooms. |
OK, back to work. (After all, idle hands are the Devil’s plaything.) As soon as we know the folder size we can use code like this to determine if that size is greater than or equal to a specified value (in this case, 25 megabytes):
If intFolderSize >= 25 Then
If the size is less than 25 megabytes, then we’re done; because the size is within the allowed limits we don’t have to delete anything. If the size is greater than (or equal to) 25 megabytes, however, our next step is to use this line of code to retrieve a collection of all the files in the folder:
Set colFiles = objFolder.Files
Once we have the collection in hand we set up a For Each loop to loop through each and every file in the folder. Inside the loop, the first thing we do is assign the file Path to a variable named strFile, then assign the file creation date and time (the DateCreated property) to a variable named dtmFileDate:
strFile = objFile.Path dtmFileDate = objFile.DateCreated
So far so good, right? We then compare the value of dtmFileDate to the variable dtmOldestDate:
If dtmFileDate < dtmOldestDate Then
If the value of dtmFileDate (for example, 1/1/2007) is less than the value of dtmOldestDate (for example, 2/2/2007) that can mean only one thing: this particular file is – so far anyway – the oldest file in the folder. Therefore, we assign the file’s creation date to dtmOldestDate, and assign the file path to a variable named strOldestFile:
dtmOldestDate = dtmFileDate sttrOldestFile = strFile
See what we’re doing there? That’s right: we’re just using these two variables to keep track of the oldest file in the folder, replacing the values of the two variables each and every time we run into a file older than any other file we’ve looked at.
After that we loop around and repeat the process with the next file in the collection. When we’re done, the path to the oldest file in the collection will be stored in the variable strOldestFile. In turn, that means we can delete the oldest file in the folder simply by passing that variable to the DeleteFile method:
objFSO.DeleteFile(strOldestFile)
And that should do it.
Incidentally, it should be obvious which side the Scripting Guy who writes this column takes in the great Pepsi vs. Coke debate. However, even though he doesn’t like Coke very much, the Scripting Guy who writes this column would never disparage anyone who does prefer Coke over Pepsi. The truth is, he refuses to say anything bad about Coke at all, even though the fact that Pepsi is sold at the Vatican Museum does suggest that Pepsi is the official soft drink of heaven.
Not that Coke drinkers have to worry much about making it to heaven, mind you.
Legal and theological disclaimer. The preceding statements do not represent the opinions of Microsoft, Pepsi-Cola, Coca-Cola, the Vatican Museum, or heaven. Although the Scripting Editor does seem to think that the Scripting Guy who writes this column is really on to something. Oops; never mind. Turns out that that the Scripting Editor thinks that the Scripting Guy who writes this column is on something. That’s a little different. |
0 comments