I want to add today’s date to a file name

        $Date = Get-Date -Format "MMddyyyy"

How do I append that to a file name? I’ve tried

$file=Get-Item $scriptPath\*.csv
Rename-Item $file $file_$Date.csv

But that just renames the file with the date. How do I take the existing name and add $date to it? ($file will only point to one file name, but the file name is random, that’s why I do it that way)

Thanks

3 Spice ups

Try this instead:

Rename-Item $file "$($file)_$Date.csv"

You could also do this (though it makes a call to Get-Date each time which might not be good in a loop):

Rename-Item $file "$($file)_$(Get-Date -Format MMddyyyy).csv"

Edit (further explanation): Basically, when the second argument in the Rename-Item cmdlet was being parsed, it was seeing the underscore as part of a variable name (since it’s a valid character in a variable name) instead of as just another character between two separate variables. Since $file_ is not defined, it would evaluate to null and appends the remainder of the expression to it which is why you would only get a .csv file with the date as the name.

2 Spice ups

I have also accomplished this by concatenating strings together.

For example, something like this:

$Date = Get-Date -Format “MMddyyyy”
$name = “name_of_file”
$filename = $name + $date + “.csv”

2 Spice ups

Get-Item is returning an object, so you can’t just rename the file that way.

$Date = Get-Date -Format "MMddyyyy"
$FileList=Get-Item $scriptPath\*.csv
$FileList | foreach {Rename-Item $_.fullname "$_.fullname-$Date"}
3 Spice ups

Good catch.

Wouldn’t this:

$FileList | foreach {Rename-Item $_.fullname "$_.fullname-$Date"}

just put the date at the very end of the file name (even after the extension)?

I checked into some of the file object properties and it looks like this is more along the lines of what the OP is looking for:

$FileList | foreach {Rename-Item $_.fullname "$_.directoryname\$($_.basename)_$Date$_.Extension"}
1 Spice up

Absolutely right, I missed that.

2 Spice ups

There are some interesting things to note here.

$file will contain System.IO.FileInfo objects. The ToString method for that class returns the same as FullName contents. So you can simply just quote the variable “$file” (if it is a single item or quote the current item during iteration) rather than $file.FullName.

Rename-Item is a good candidate for delay-bind script block. That would make this rename process concise and more inline, especially since you aren’t changing directories.

$file | Rename-Item -NewName { $_.BaseName + "_$Date.csv" }
# or if you don't like concatenation
$file | Rename-Item -NewName { "$($_.BaseName)_$Date.csv" }

Why does the above work? Well, the -NewName parameter is the correct, assigned object type. $file contains the PsPath property, which binds to -LiteralPath in Rename-Item. Then you pass the scriptblock to -NewName and the delay bind will execute the block after the pipeline element is sent through rather than when the command is executed.

2 Spice ups

It’s little things like this that I always find interesting and, occasionally, frustrating about PowerShell. There are often numerous ways to do basically the exact same thing but just a little bit differently thanks to things like implicit calls to an object’s ToString function simply by quoting the variable containing it. It’s definitely the sort of thing you just don’t get in complied languages (which tend to be strongly typed anyway).

I think it is more readable to access the member FullName anyway. I just wanted to add my two cents even if it’s worth a half cent.

1 Spice up