I have a folder that contains a bunch of Photos. The default name for the photo was something like IMG01.JPG. I wanted to organize them by date and rename them using the date the photo was taken.
#Defining function Get-DateTaken that will get the Date Taken of a JPG file
function Get-DateTaken
{
#Define Parameters of this function
param
(
#This will allow the function to be compatible to use in a Pipeline
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[String]
$Path
)
begin
{
$shell = New-Object -COMObject Shell.Application
}
process
{
$FileProperties = 1 | Select-Object -Property Name, DateTaken, Folder
$FileProperties.Name = Split-Path $path -Leaf
$FileProperties.Folder = Split-Path $path
$shellfolder = $shell.Namespace($FileProperties.Folder)
$shellfile = $shellfolder.ParseName($FileProperties.Name)
$FileProperties.DateTaken = $shellfolder.GetDetailsOf($shellfile, 12)
$FileProperties
}
}
#Define the path of the photos
$Path = "C:\users\kenny\downloads\test"
#To get all the .JPG files from the folder specified
$Files = Get-ChildItem $Path "*.jpg"
#Define a counter to name Photos taken on the same date with the Counter following the date.
#For example 02-02-2021.JPG, 02-02-2021-1.JPG, 02-02-2021-2.JPG
$Counter = 1
Foreach($File in $Files){
$FilePath = $Path + "\" + $File.name
$DateTaken = Get-ChildItem $Path\$File | Get-DateTaken
#The DateTaken has a format of mm/DD/yyyy. The '/' will throw an error because it is part of a path.
#we will replace the '/' with a '-'
$NewName = ($DateTaken.DateTaken.substring(0,$DateTaken.DateTaken.IndexOf(' '))).replace('/','-') + ".jpg"
If(-Not(Test-Path $Path\$NewName)){
Rename-Item -Path $FilePath -NewName $NewName
Write-Progress "$FilePath has been renamed to $NewName."
}
Else{
$NewName = ($DateTaken.DateTaken.substring(0,$DateTaken.DateTaken.IndexOf(' '))).replace('/','-') + "-" + $counter + ".jpg"
Rename-Item -Path $FilePath -NewName $NewName
Write-Progress "$FilePath has been renamed to $NewName."
$Counter = $Counter + 1
}
}
The Date Taken is not part of the file property. One way to obtain that information is to use the Shell.Application COM object. Different file type will have a different number of extended properties. You can replace ‘320’ below to something like ‘1000’ to make sure you get every single properties. For the purpose of this script, Date Taken is 12. Hence, we are putting ’12’ in $shellfolder.GetDetailsOf($shellfile, 12)
$File = "C:\users\kenny\downloads\test"
$shell = New-Object -COMObject Shell.Application
$FileProperties = 1 | Select-Object -Property Name, DateTaken, Folder
$FileProperties.Name = Split-Path $File -Leaf
$FileProperties.Folder = Split-Path $File
$shellfolder = $shell.Namespace($FileProperties.Folder)
$shellfile = $shellfolder.ParseName($FileProperties.Name)
$FileProperties.DateTaken = $shellfolder.GetDetailsOf($shellfile, 12)
0..320 | Foreach-Object { '{0} = {1}' -f $_, $ShellFolder.GetDetailsOf($null, $_) }


I have a few files that have the same Date Taken properties. They will be renamed with a dash and the counter number. The Write-Progress cmdlet will display the progress of this script.


This is what I have in the same folder after running the script. The Date Taken matches the file name.