Organize Media Files with PowerShell

I’ve never been happy with the way Windows imports photos, so I decided to look for a better way. I found this post on Steve Smith’s blog about how to rename photos and organize them using a PowerShell script. The script extracts the date each photo was taken from the file’s EXIF data, renames the files with the date, and organizes them into folders based on the month. This was close to what I wanted, but I also wanted to do the same thing with videos. Unfortunately, videos don’t contain the same kind of EXIF data. After some research and experimentation, I figured out how to extract the Media Created date from MP4 and AVI files.

My script recurses through the $SourceRootPath looking for any files with an extension in $FileTypesToOrganize. For each file, it extracts the appropriate creation date. In the case of JPG files, this comes from the EXIF DateTaken and for other file types this comes from the MediaCreated date. Using the date and the $DestinationRootPath it builds a path of the following format:

$DestinationRootPath\yyyy\MM_MMMM\yyyy-MM-dd HH.mm.ss.[ext]

Right now the script only works with JPG, MP4 and AVI files; however, it would probably work with other video formats simply by adding them to the list of extensions.

You can download my script here.


18 Responses to “Organize Media Files with PowerShell”

  • Patrick

    Hi, any way you could modify this to use the windows file property created date instead? I notice the on the mp4 files that my samsung device created Media created date isn’t populated. i cam as far as finding an example… 😉 http://technet.microsoft.com/en-us/library/ee176988.aspx#EBAA

    • Patrick

      or/and maybe use the windows file property created date to polulate the exif media created date property? hope you understnad what i mean…

      • todd

        Patrick,
        Thanks for the feedback. I’m not sure I would want to use the file’s creation date in my script as that date usually isn’t very reliable. For example, doing things like copying files or extracting them from a zip file, often seems to change those dates. However if you want, you could edit the file to do that. What you would do is edit the GetCreationDate function to use the file’s CreationTime property for the appropriate extension. So I think you would edit it to look like this:

        function GetCreationDate($File) {
        switch ($File.Extension) {
        ".jpg" { $CreationDate = GetDateTakenFromExifData($File) }
        ".3gp" { $CreationDate = GetCreatedDateFromFilename($File) }
        ".mp4" { $CreationDate = $File.CreationTime }
        default { $CreationDate = GetMediaCreatedDate($File) }
        }
        return $CreationDate
        }

        Keep in mind that if you do this it will always use the CreationTime even if the MediaCreatedDate exists.

        Also, you should grab the latest version of my script first as I made a couple minor changes.

        I hope this helps.

        Todd

  • Joe

    Todd, I cant find anything like your script in any of the video programs (eg Adobe Premier Organiser). Nice Work 🙂

    I’d like to be able to take the ‘Media Created’ date and put it into the ‘Date Modified’ field. ?

    There are a few mini programs that will allow changed to Dates Created, Modiefied and Accessed – but NOT using the ‘Media Created’ date. Any suggestions most welcome! Thx Joe

  • MairaV

    Hi, I have been trying your script and works like a charm with jpg. But it doesn’t recognize the .mp4 date, it says: “Unable to determine creation date of file”.

    Any idea why is this happening?

    • todd

      Most likely, your file does not have a Media Created date set. If you right-click on the file, view the properties and go to the Details tab. In the Origin section there is a property called “Media created”. Is there a value set there? Not all sources set this value. Note, this is not the same as the “Date created” or “Date modified” properties. I’ve avoided using those values, because they are very unreliable. It’s easy for those values to change and not reflect when the photo or video was originally taken.

      Todd

  • wildcowboy

    Hello Todd, Would you mind to advise how can the script can be used on a Windows machine? Do I need to install a 3rd party software? I actually looking for a way to copy File Creation date to Media created date for MP4 files. I think “Media created” is “System.Media.DateEncoded” property

  • Andrew

    Hi, unfortunately most of my mp4 and avi files do not have “Media created” date written in them. Do you know if copying of the file creation date to the media created field could be done in powershell? I believe the media created is the property id 191. File creation date is reliable in my case because I have copied “ContentCreateDate” to FileCreateDate for each file using ExifTool. Unfortunatelly ExifTool cannot write Media created (EncodingTime)tag so I need to find a way to do that in order to be able to use the script. Any thoughts would be much appreciated.

  • Geoffrey Uys

    The script had problems on Windows 10, I found that the “Media created” date was 209 not 191, so it was an easy fix. An improvement to make the script OS agnostic would be to detect OS version and adjust the date accordingly.
    Another change I made was to not return null but rather get the modified date for files that did not have EXIF data or Media created.

  • Wp

    Hi,

    Unlike the above, my mp4’s DO have “media created” under details->origin. However for I still get “Unable to determine creation date of file.”

    Any idea? I’m on Windows 10 Pro 1803 x64
    I’m on

  • Brent V

    I think you want 208, not 209 for Widnows 10

  • Roberto

    I was not able to download your script. Is the link still active?

  • M&M

    the GetMediaCreatedDate function is not returning the value for a file that has the Media Create value populuated. I simplified the code for troubleshooting purposes. Can you help me?

    [reflection.assembly]::loadfile( “C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll”)

    function GetMediaCreatedDate($File) {
    $Shell = New-Object -ComObject Shell.Application
    $Folder = $Shell.Namespace($File.DirectoryName)
    $CreatedDate = $Folder.GetDetailsOf($Folder.Parsename($File.Name), 191).Replace([char]8206, ‘ ‘).Replace([char]8207, ‘ ‘)

    if (($CreatedDate -as [DateTime]) -ne $null) {
    return [DateTime]::Parse($CreatedDate)
    } else {
    return $null
    }
    }

    $Files = Get-ChildItem “D:\Pictures\E\Pictures\2019-10-21\2019-10-Anniversary\IMG_3730.MOV”

    foreach ($File in $Files)
    {
    $MediaCreateDate = GetMediaCreatedDate $File
    Write-Host $MediaCreateDate
    }