Hey, Scripting Guy! How Can I Create File Names Based on Their Time Stamp?

ScriptingGuy1

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I create a file name from the date? I have this application that creates a log file, and every hour I would like to save that log file as a file whose name is generated from the current time stamp. Can this be done?

– RH

SpacerHey, Scripting Guy! Answer

Hi RH,

Ever since I read your e-mail message, I have had this old Rolling Stones tune stuck in my head (which is much better than having “I’ve got a brand new pair of roller skates…”), and it is causing some serious brain itch. So I was back in Munich, Germany, a couple of years ago, and the Stones were on stage. It was a fine spring evening, ink-black sky, full moon, and not a cloud in the sky. The lights went off and two flame pots erupted. The crowd went wild and…sorry.

The main logic of today’s script is contained in a function we have called GetFileName. Inside this function we use a couple of pretty cool methods to create the file name for you. Here’s the sscript:

Function GetFileName([ref]$fileName)
{
 $invalidChars = [io.path]::GetInvalidFileNamechars() 
 $date = Get-Date -format s
 $fileName.value = ($date.ToString() -replace "[$invalidChars]","-") + ".txt"
}

$fileName = $null
GetFileName([ref]$fileName)
new-item -path c:\fso -name $filename -itemtype file

The first thing we do is create a function named GetFileName. To do this we use the function keyword, and give it the name of the function. We are going to pass a variable to the function by reference. VBScript functions are talked about here. When we pass a variable to a function by reference, it means we will be changing the value of the variable inside the function, and then handing that value back to the code that called the function.

Another way to call a function is to pass a variable by value. When that happens, the value of the variable is what is important. Inside the function the value of the variable may change, but when the script is done, the value of the variable remains unchanged. This is seen here in this demo script:

Function addOne($in)
{
 $in = $in + 1
 'In the function $in equals ' + $in 
}
$in = 1
addOne($in)
'Out of the function $in equals ' + $in

Back to the GetFileName function—when you want to pass a variable by reference, you need to use the [ref] type constraint to make the variable into a reference type. This is seen here.

Function GetFileName([ref]$fileName)

Next we need to get a list of all the things you are not allowed to have in a file name. Dude! You mean you cannot remember all the things you are not allowed to have in a file name? (Uh, join the club.) I know some of the things, and I know some things that I do not like in file names (such as spaces), but that is about it. I generally stick with letters and numbers for my file names. But suppose you needed to know exactly what you could not have in a file name; how would you do that? Well it is easy. You can use the GetInvalidFileNameChars method from the System.Io.Path .NET Framework class. If you would like to see a list, copy this code into the Windows PowerShell command window, as seen here:

Image of a listing of invalid file name characters

 

In our script, we store the invalid file name characters into an array named $invalidChars. This is shown here:

$invalidChars = [io.path]::GetInvalidFileNamechars()

Now we want to get the current date and time. We use a .NET Framework standard format string. These are documented on MSDN. Using the standard format strings is very easy. You use the –format parameter, and then include the format in which you want the date to be displayed. An example of the use of some of these format strings is seen here:

Image of different date formats

 

In our script, we want to store the date in the sortable fashion. A sortable date places the year, month, and day first, separated by the letter T, and then followed by the hour, minute, and second. This is seen here:

$date = Get-Date -format s

Next we need to get rid of the invalid characters that are not permitted in a file name. To do this, we use the invalid characters we stored in the $invalidChars and feed it as a regular expression pattern to the replace operator. The second parameter of the replace operator is what we are going to replace it with. We use the dash (“–”) for all the invalid characters. We also append .txt to the end of our file name, and assign it to the value of the $filename reference variable. This is seen here:

$fileName.value = ($date.ToString() -replace "[$invalidChars]","-") + ".txt"

Now we are outside of the function. To use a variable as a reference, it must first be present. In Windows PowerShell we do not need to use the DIM command to declare a variable. In fact if we want to create a variable, we just assign a value to it. This is seen here:

$fileName = $null

We now want to call the GetFileName function. To do this, we pass the $fileName variable to it. Note that the [ref] type is required. This is seen here:

GetFileName([ref]$fileName)

Finally we use the new-item cmdlet to create a new file. We specify the path to the path parameter, and the name we created in the $filename variable. To create a file, we specify the item type as file. This is seen here:

new-item -path c:\fso -name $filename -itemtype file

When the script is run, it creates an empty file in the fso folder. I ran the script several times (I am easily entertained). The results are seen here:

Image of the results of running the script multiple times

 

Well, RH, I hope you found this article useful. We have explored creating file names, date types, format strings, and all kinds of other cool stuff. Happy New Year! May 2009 be one of peace for you and for the planet.

Ed Wilson and Craig Liebendorfer, Scripting Guys

0 comments

Discussion is closed.

Feedback usabilla icon