1

Usecase:

There are ~4000 files that have lost any relation to the date they were created, and as a result the order totally mixed up. After copying the entire directory to Windows i saw what the problem is: Android doesn't store the creation timestamp of a file, and sorts only by Last Modification time of the file. Whereas the "Modification Time" was the "broken" attribute which caused all my files to get out of their order: enter image description here

From here i know how to proceed - just copy the "Date" attribute into the "Date Modified" for every single file, and i would do it with the following code:

$picts =  Get-ChildItem -force | Where-Object {! $_.PSIsContainer} 
foreach($object in $picts)
{
      $object.LastWriteTime=($object.Date)
}

The problem is that $object.Date is a wrong argument, because Date doesn't seem to represent the "Date" attribute of the file in Powershell.

Does anybody know what is the right ChildItem to represent the "Date" or/and "Date taken" attributes?

Dharman
  • 30,962
  • 25
  • 85
  • 135
faceless
  • 450
  • 4
  • 15
  • 1
    Check this: https://stackoverflow.com/questions/6834259/how-can-i-get-programmatic-access-to-the-date-taken-field-of-an-image-or-video – sodawillow Apr 08 '20 at 14:08

2 Answers2

1

You can obtain the Date Taken value programatically by loading the picture as an Image and then retrieving the appropriate property:

function Get-DateTaken
{
  param(
    [ValidateNotNull()]
    [System.IO.FileInfo]$File
  )

  # Ensure System.Drawing assembly is available
  Add-Type -AssemblyName System.Drawing

  try{
    # Attempt to load image file from disk
    $img = [System.Drawing.Image]::FromFile($File.FullName)
    try{
      # Get the System.Photo.DateTaken property
      $dateTakenValue = $img.GetPropertyItem(36867).Value

      # Decode to string
      $dtString = [System.Text.Encoding]::UTF8.GetString($dateTakenValue)

      # Parse as DateTime, property string is in the format `yyyy:MM:dd HH:mm:ss\0`
      $dt = [datetime]::Now
      if([datetime]::TryParseExact($dtString.Trim(0), 'yyyy:MM:dd HH:mm:ss', $null, 'None', [ref]$dt)){
        # Success, return DateTime
        return $dt
      }
    }
    catch{
    }
  }
  finally{
    # Clean up
    $img.Dispose()
  }
}

Now that we can translate a FileInfo reference to the corresponding date, we can do:

$picts =  Get-ChildItem -Force | Where-Object {! $_.PSIsContainer} 
foreach($object in $picts) {
  if(($DateTaken = Get-DateTaken $object)){
    $object.LastWriteTime = $DateTaken
  }
}
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
0

I don't have imported pictures from an Android phone so this will be a more general answer to how you can troubleshoot things like this.

If you take an arbitrary file in your collection with Get-ChildItem you can see all the different meta data it has by doing the following:

$test = Get-ChildItem "Yourfile.jpg"
$test.LastWriteTime | Get-Member

This will show you both the type of the object (in this case System.DateTime) and will also give you a list of all methods you can use with it. If you want to understand what the $object.Date is in your example, I would use the same approach and pipe $object.Date to Get-Member to see what type of object it is. If they are different, you would have to convert the $object.Date into a System.DateTime before you can change the modification date of the file.

Tanaka Saito
  • 943
  • 1
  • 17
  • 40