I'm trying convert a bunch of pictures and videos, but when I convert it to a new format I obviously lose the properties of the original file. I'd like to be able to read the "Date taken" property from the old file and update it on the new one using powershell.
Asked
Active
Viewed 1.8k times
4 Answers
17
I can't test it right now (don't have any images with XIF data laying around, but I think this should work:
[reflection.assembly]::LoadWithPartialName("System.Drawing")
$pic = New-Object System.Drawing.Bitmap('C:\PATH\TO\SomePic.jpg')
$bitearr = $pic.GetPropertyItem(36867).Value
$string = [System.Text.Encoding]::ASCII.GetString($bitearr)
$DateTime = [datetime]::ParseExact($string,"yyyy:MM:dd HH:mm:ss`0",$Null)
$DateTime

OutOfThisPlanet
- 336
- 3
- 17

EBGreen
- 36,735
- 12
- 65
- 85
-
1This is half the story I can get the dateTken from a picture, how about a video (mpg, wmv)? – JNappi Jul 27 '11 at 00:51
-
Hmm...I'll do some poking around. I'm not sure to be honest. – EBGreen Jul 27 '11 at 06:02
-
10This returns a bite array. To convert this to [datetime] you will need to do the following: ``$bitearr = $pic.GetPropertyItem(36867).Value $string = [System.Text.Encoding]::ASCII.GetString($bitearr) [datetime]::ParseExact($string,"yyyy:MM:dd HH:mm:ss`0",$Null)`` – Davor Josipovic May 06 '13 at 21:53
-
2Alternatively omit the null character from the array using `$bitearr[0..18]` and use `yyyy:MM:dd HH:mm:ss` as the date pattern ... you can also now use `Add-Type -AssemblyName System.Drawing` instead of reflection. – Ruskin Feb 10 '19 at 08:32
7
In general, you can access any extended property for a file shown in explorer through the shell GetDetailsOf
method. Here's a short example, adapted from another answer:
$file = Get-Item IMG_0386.jpg
$shellObject = New-Object -ComObject Shell.Application
$directoryObject = $shellObject.NameSpace( $file.Directory.FullName )
$fileObject = $directoryObject.ParseName( $file.Name )
$property = 'Date taken'
for(
$index = 5;
$directoryObject.GetDetailsOf( $directoryObject.Items, $index ) -ne $property;
++$index ) { }
$value = $directoryObject.GetDetailsOf( $fileObject, $index )
However, according to the comments on another question, there is no general-purpose mechanism for setting these properties. The System.Drawing.Bitmap
class that EBGreen mentioned will work for images, but I'm afraid I also do not know of a .NET option for video files.

Community
- 1
- 1

Emperor XLII
- 13,014
- 11
- 65
- 75
-
-
1`$property = 'Date taken'` is used to find the index of the "Date taken" property, and the shell objects are used to read that property for the file. – Emperor XLII Dec 28 '16 at 18:45
1
This works for me, thanks to the above help and others.
try{
Get-ChildItem C:\YourFolder\Path | Where-Object {$_.extension -eq '.jpg'} |
ForEach-Object {
$path = $_.FullName
Add-Type -AssemblyName System.Drawing
$bitmap = New-Object System.Drawing.Bitmap($path)
$propertyItem = $bitmap.GetPropertyItem(36867)
$bytes = $propertyItem.Value
$string = [System.Text.Encoding]::ASCII.GetString($bytes)
$dateTime = [DateTime]::ParseExact($string,"yyyy:MM:dd HH:mm:ss`0",$Null)
$bitmap.Dispose()
$_.LastWriteTime = $dateTime
$_.CreationTime = $dateTime
}}
finally
{
}

Andrew Cleveland
- 11
- 1
0
To read and write the "date taken" property of an image, use the following code (building on the answer of @EBGreen):
try
{
$path = "C:\PATH\TO\SomePic.jpg"
$pathModified = "C:\PATH\TO\SomePic_MODIFIED.jpg"
Add-Type -AssemblyName System.Drawing
$bitmap = New-Object System.Drawing.Bitmap($path)
$propertyItem = $bitmap.GetPropertyItem(36867)
$bytes = $propertyItem.Value
$string = [System.Text.Encoding]::ASCII.GetString($bytes)
$dateTime = [DateTime]::ParseExact($string,"yyyy:MM:dd HH:mm:ss`0",$Null)
$dateTimeModified = $dateTime.AddDays(1) # Set new date here
$stringModified = $dateTimeModified.ToString("yyyy:MM:dd HH:mm:ss`0",$Null)
$bytesModified = [System.Text.Encoding]::ASCII.GetBytes($stringModified)
$propertyItem.Value = $bytesModified
$bitmap.SetPropertyItem($propertyItem)
$bitmap.Save($pathModified)
}
finally
{
$bitmap.Dispose()
}

arni
- 2,152
- 19
- 14