How Can I Rename Files Based on the File’s Creation Date?

How Can I Rename Files Based on the File’s Creation Date?

  • Comments 1
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! I have a folder that contains a bunch of log files. I would like to rename each file based on the date the file was created; for example, if a file was created on December 1, 2004, I’d like to rename it 20041201.log. Is that possible?

-- CK

SpacerHey, Scripting Guy! AnswerScript Center

Hey, CK. Listen, when it comes to scripting, anything is possible. (Well, except for the things that aren’t possible, of course.) And while dates can often times be tricky to work with in your WMI scripts, this is one time when WMI’s date format actually makes it easy to carry out a task.

To help explain how to do this, let’s break the task into two pieces. First, how do we list all the files in a folder, as well as their creation dates? Well, one way is to use a script similar to this:

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

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

For Each objFile In FileList
    Wscript.Echo objFile.CreationDate
Next

In this script, we bind to the WMI service and then use an association query to return a collection of all the files in the folder C:\Logs. If you aren’t familiar with association queries, they do pretty much what the name implies: they provide a way to associate two separate WMI classes, in this case, Win32_Directory and CIM_DataFile. The net effect is that this enables us to get back a collection of all the files in the associated folder.

After we have all the files, we simply create a For-Each loop, and then echo the value of the CreationDate property for each of these files. Because WMI uses the UTC (Universal Time Coordinate) format, we’ll get back values that look like this:

20041201202723.695209-480

Sure, that’s weird-looking, but guess what: the first eight characters happen to correspond to the year, month, and day, the very values you want to use as file names. You want a file name like 20041201? Take a look at the first eight characters in our UTC date: 20041201202723.695209-480. Just what the doctor ordered.

In fact, to get the file name, all we need to do is use VBScript’s Left function to grab those first eight characters in our UTC date. This modified script takes those first eight characters, stores them in a variable named strDate, and then echoes that value:

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

Set FileList = objWMIService.ExecQuery _
    ("ASSOCIATORS OF {Win32_Directory.Name='c:\Logs'} Where " _
        & "ResultClass = CIM_DataFile")

For Each objFile In FileList
    strDate = Left(objFile.CreationDate, 8)
    Wscript.Echo strDate
Next

So much for step 1. Now it’s time for the second - and final - step: renaming each of the files. Let’s show you the script, and then explain how it works:

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

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

For Each objFile In FileList
    strDate = Left(objFile.CreationDate, 8)
    strNewName = objFile.Drive & objFile.Path & strDate & "." & "log"
    errResult = objFile.Rename(strNewName)
Next

The tricky part here lies in constructing the new file name. When you rename a file using WMI, you can’t just specify a new name; for example, we can’t simply rename the file Wednesday.log to 20041201.log. Instead, we have to specify the entire path, and rename the file C:\Logs\20041201.log. That’s what this line of code does:

strNewName = objFile.Drive & objFile.Path & strDate & ".log"

What we’re doing here is combining the drive where the file resides (C:), the folder path on that drive (\Logs\), the new name for the file (20041201, the value of our variable strDate), and the new file extension (.log). Put those all together, and you end up with C:\Logs\20041201.log, which just happens to be the complete path we want to assign the file. All we have to do now is call the Rename method and we’ll change the file name.

Incidentally, we know it seems a bit odd to have to supply the entire path just to rename a file. If there’s a bright side to this, however, it’s the fact that you can use this same approach to move files to another folder. For example, suppose you not only wanted to rename the files, but you also wanted to move them to a folder name C:\Backups. In that case, you could use a script similar to this, which replaces the current file path (\Logs\) with the new path (\Backups\). Run this script, and the files will not only be renamed, they will also be moved to C:\Backups:

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

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

For Each objFile In FileList
    strDate = Left(objFile.CreationDate, 8)
    strNewName = objFile.Drive & "\Backups\" &  strDate & ".log"
    errResult = objFile.Rename(strNewName)
Next

The only problem with the script we’ve shown you is that it will blow up if you have files with the same creation date; after all, the script will try to create two files named, say, 20041201.log, and the file system just doesn’t like to have identically-named files in the same folder. If that’s an issue, here’s a sample script that checks to see if a file name is unique before it actually renames the file. For example, suppose the folder already has a file named 20041201.log. If that happens, this script (which we won’t explain in detail today) will create a new file name: 20041201_2.log and check to see if that file exists. If it does, it will try 20041201_3.vbs, and continue trying until it creates a unique name. At that point it renames the file:

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

Set FileList = objWMIService.ExecQuery _
    ("ASSOCIATORS OF {Win32_Directory.Name='c:\Logs'} Where " _
        & "ResultClass = CIM_DataFile")

For Each objFile In FileList
    strDate = Left(objFile.CreationDate, 8)
    strNewName = objFile.Drive & objFile.Path & _
       strDate & "." & "log"
    strNameCheck = Replace(strNewName, "\", "\\")

    i = 1
    Do While True
        Set colFiles = objWMIService.ExecQuery _
            ("Select * from Cim_Datafile Where Name = '" & strNameCheck & "'")
        If colFiles.Count = 0 Then
            errResult = objFile.Rename(strNewName)
            Exit Do
        Else
            i = i + 1
            strNewName = objFile.Drive & objFile.Path & _
                strDate & "_" & i & "." & "log"
            strNameCheck = Replace(strNewName, "\", "\\")
        End If
    Loop
Next

Yes, it’s a little complicated, which is why we’re saving the explanation for another day. Hey, you don’t really expect to put in any overtime on this column, do you?

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Good example and nice showcase of avoiding trouble.