0

I have a bunch of .jpg files spared into different folders with a false timestamp on the filename (1 hour delay) and I want to correct that according to the creation time. The goal of this is to get one CSV sheet containing all the corrected filenames with their full path.

I am now trying to write a PowerShell script that can go through all the folders, extract the creation time and replace it on the filenames with a false timestamp. Below a small example:

Original filename with false timestamp:

Filename, Created Date, Modified Date
20180524010500530_FR785101.jpg, 2018-05-24 00:05:00, 2018-05-24 00:05:34

The correct output would be:

Filename, Created Date, Modified Date
20180524000500530_FR785101.jpg, 2018-05-24 00:05:00, 2018-05-24 00:05:34

I have started to document myself on the use of the CreationTime command but I still cannot figure out how I can extract the creation time and replace it into the filename timestamp. Also, I don't know how I can make the script run through all the folders and sub-folders containing the image files, to finally export everything into a CSV sheet.

Get-ChildItem -Path "c:/path/to/files/" -Recurse -Include @("*.jpg") |
    Rename-Item -NewName {
        $_.Name -replace "IMG", ($_.CreationTime.ToString("yyyyMMdd"))
    }

UPDATE:

The final .csv output i would like to get looks like this:

File path, date time, name
path_of_file, Timestamp, Name
C:_users_mind_volume, 20180524000500530, FR785101
  • `"IMG"` -> `'^\d{8}'`. Replace the first 8 digits in a filename with the creation date. – Ansgar Wiechers Jul 01 '18 at 11:36
  • @AnsgarWiechers thank you for the answer but can you be more specific, i couldn't understand your approach so well. – Wade Blackmore Jul 01 '18 at 13:03
  • Please read up on the [`-replace` operator](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-3.0#replacement-operator) and [regular expressions](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_regular_expressions?view=powershell-3.0). – Ansgar Wiechers Jul 01 '18 at 13:08

2 Answers2

1

you'd be looking for something like this to rename a file with the correct date/time.

#Rename file directly to correct format.
Get-ChildItem -Filter '*.jpg' -Recurse | ForEach-Object {
    $NewTimestamp = $_.CreationTime.ToString('yyyyMMddHHmmss')
    Rename-Item -LiteralPath $_.FullName -NewName ($_.BaseName -replace '.*(_.*)',($NewTimestamp+'$1'+$_.Extension)) -WhatIf
}

This will just export them to a csv on your desktop.

#Export details to CSV
Get-ChildItem -Filter '*.jpg' -Recurse | Select FullName,CreationTime,LastWriteTime | Export-Csv -Path "~\Desktop\Images.csv" -NoTypeInformation
colsw
  • 3,216
  • 1
  • 14
  • 28
  • thanks for your answer, but can you tell me how i can make this run through all the folders and sub-folders and give me the full path of each file, i have updated the question with the exact output i want on the .csv sheet – Wade Blackmore Jul 01 '18 at 13:07
  • 1
    Changing Name -> FullName in the Select part will give you the full path of all the files, the `-Recurse` in `Get-ChildItem` already runs through all sub folders. – colsw Jul 01 '18 at 13:19
  • cool, this looks good but its just replacing the whole file name by the creation date, it is not replacing only the 8 first digits, is it possible to add something that corrects that ? – Wade Blackmore Jul 01 '18 at 13:50
  • @WadeBlackmore I ran this against one of the filenames you posted, it works fine for me. what filename are you running it against? – colsw Jul 01 '18 at 14:28
  • @ConnorLSW fine now, i just had another issue that i needed to fix but the other problem for me now is to change the separators in the full path, because the full path is separated with `/` and i want it to be separated with a `_`. so is it possible to do that also ? – Wade Blackmore Jul 01 '18 at 15:33
  • 1
    @WadeBlackmore why exactly are you looking to replace them with `_`? are you looking to turn the entire path into the filename? you might want to ask a new question laying down your ideal end result rather than asking individual questions. – colsw Jul 01 '18 at 15:40
  • @ConnorLSW actually, i didn't think about it at first but when i export the .csv sheet to excel and i want to use separators, then i have two types of separators which are the `/` and the `_` and i need the full path to be separated with underscores because i need the data contained in each full path. I have updated now the question but i will make it more specific – Wade Blackmore Jul 01 '18 at 15:44
  • @WadeBlackmore the CSV should be delimited by `;` or `,` not a slash, so it shouldn't really matter. you can always change the `FullName` in select to `@{n='FullPath';e={$_.FullName -replace '/','_'}}` to do this though. – colsw Jul 04 '18 at 10:49
0

The following solution:

  • passes a script block directly to -NewName in order to calculate the new file name (as also used in your question), which is more efficient (and more concise) than using a ForEach-Object call whose script block calls Rename-Item in each iteration.

  • uses -PassThru to output the renamed files, which enables piping to Export-Csv in order to rename the files and create the CSV file in a single pipeline.

  • uses calculated properties in order to transform and rename the properties of interest for the output CSV file.

Get-ChildItem -Path "c:/path/to/files" -File -Recurse *.jpg | 
  Rename-Item -WhatIf -PassThru -NewName { 
     '{0}_{1}' -f $_.CreationTime.ToString('yyyyMMddHHmmssfff'),
                  ($_.Name -split '_')[1] 
    } | 
        Select-Object @{ n='path_of_file'; e={ $_.FullName -replace '\\', '_' } }, 
                      @{ n='Timestamp'; e={ ($_.BaseName -split '_')[0] } }, 
                      @{ n='Name'; e={ ($_.BaseName -split '_')[1] } } |
            Export-Csv -NoTypeInformation .\out.csv

Note the -WhatIf common parameter, which only previews the renaming operations, allowing you to verify that the new names are constructed as expected.
Remove -WhatIf to perform the actual renaming.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • this solution is not working for me and i luckily made a backup before running the script because it destroyed my data – Wade Blackmore Jul 02 '18 at 17:23
  • @WadeBlackmore: On a meta note, before we dig deeper: I'm sorry to hear it didn't work. However, having made a backup shouldn't be a matter of _luck_: While answerers here (hopefully) offer solutions they've tested themselves (I have), the responsibility is always on _you_ not to blindly run potentially destructive code: either use sample files or - always - have a backup you can restore. Also, saying that the solution is not working for you without saying _in what way_ helps neither me nor you: you still don't have a solution and I don't know how to fix my answer. – mklement0 Jul 03 '18 at 02:40
  • I've corrected one problem in the code: the updated time-stamp strings were missing 3 digits (fractional seconds) at the end. Other than that, I see no problems, assuming that your input files all follow the `_.jpg` name pattern. – mklement0 Jul 03 '18 at 03:38
  • I've also added `-WhatIf` so that the renaming operations are only _previewed_ by default - see my update. – mklement0 Jul 03 '18 at 13:32