1

I'm trying to rename the file extensions of a collection .txt files while also preserving the timestamps. I first attempted to use Robocopy, but this tool can only copy files from one directory to another while preserving file timestamps (file extensions cannot be changed as far as I can tell). I used PowerRename, which makes file extension renaming easy, but it also modifies the timestamps of the renamed files.

Finally I used the Windows MOVE command to achieve this (as shown below):

MOVE "C:\Folder\Filename.txt" "C:\Folder\New_Filename.txt"

But I am having trouble doing this with file extensions (specifically renaming multiple files extensions). Because when I attempted to use this code example for my own needs, I came up with this:

 Move-Item -Path C:\Users\Elon\Downloads\notes\*.txt -Destination C:\Users\Elon\Downloads\notes\*.md

This command responds with the error "Move-Item: Illegal characters in path" - I suspected this is because I used a wildcard on the destination bit maybe? Any help would be appreciated. Thanks everyone!

Sidley
  • 43
  • 3
  • Could you provide the reason for using `Move-Item` instead of `Rename-Item` for renaming your file ? – Santiago Squarzon Feb 23 '22 at 16:46
  • Move-Item won't change the timestamps by default. Or at least this is my assumption. I could easily be wrong about that. Would you recommend using Rename-Item? – Sidley Feb 23 '22 at 17:03
  • By timestamp do you mean you want to keep the `LastWriteTime` of your files? – Santiago Squarzon Feb 23 '22 at 17:04
  • I'm referring to the 'Date Modified' column in Windows Explorer. The files I'm renaming are journal entries. So it's important that they are displayed chronologically in the new tool I'm using to view them (Obsidian). I appreciate your help. – Sidley Feb 23 '22 at 17:08

2 Answers2

1

Use Get-ChildItem to discover the target files, then move one by one:

Get-ChildItem C:\Users\Elon\Downloads\notes\ -File -Filter *.txt |Move-Item -Destination { "C:\Users\Elon\Downloads\notes\$($_.BaseName).md" }
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
1

Give this a try, basically same as Mathias's answer but this uses a foreach-object loop so we can capture the LastWriteTime before we rename the file and then after renaming it we can set the old date to the new file (here is why we use -PassThru so we can capture the object that points to the new file).

Get-ChildItem ./test/ -Filter *.txt | ForEach-Object {
    $remember = $_.LastWriteTime
    $newName = '{0}.md' -f $_.BaseName
    $newFile = Rename-Item -LiteralPath $_.FullName -NewName $newName -PassThru
    $newFile.LastWriteTime = $remember
}
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37