Organize your Digital photos into folders using Powershell and Exif data

8:58 pm in dotnet, exif, powershell by The WMI guy

This post isn’t really systemcenter related directly, but with some creative thinking it does belong on this blog. Although sms is a large portion of my professional life, I still have a somewhat personal life as well. And in that personal life, I occasionally take some pictures. And since photography has progressed into digital pictures, I obviously take digital pictures, mainly of my 3-year old son Lennart. So far so good. The problem is that these digital photos need to be copied to computers to clear the memory cards for taking additional pictures.

This is usually were nightmares start happening, it starts with copying them to your laptop, because that is the machine that was in closest proximity when the memory card needed to be emptied. The next time around you put them on your mediacenter directly and so on. The main problem I have is that I usually have to do this in a hurry, because new pictures are going to be taken that day. Which means the files DSC?????.jpg are copied to some folder (usually called ToBeOrganized) without any descriptive name added to it. After taking pictures for a couple of months, getting this ToBeOrganized folder organized seems like a hell of a job. So I decided to call in Windows Powershell to assist.

For those of you that have been living under a rock for the post couple of months, Windows powershell is Microsoft’s new dos-box that has everyone running around overly excited. The neat thing about this dos-box is that it can access Dotnet classes, and that is exactly what I figured I would do to get my pictures organized.

I started of my endeavor by reading a blog post from James O’Neill’s blog. In his blog post James talks about accessing Exif data from within powershell, and that is exactly what I did, armed with the knowledge of that blog post I created one of my first Powershell scripts. The code isn’t really pretty, but it reads the Datapicturetaken property from the Exif data of all pictures in the folder where the script was launched from. Subsequently it copies all these files into a new folder called c:\organizedfotos. Underneath this folder you get a folder per year, followed by a folder per “picture date”. So in the end your folders are organized like this.



Now, all I need to do is analyze each folder to see what event triggered the creation of these pictures, rename the folder. Archive each year to Dvd, and finally decide which one we are going to print. How did I do all this will with a simple script. The Script looks like this:

# ==============================================================================================
# Microsoft PowerShell Source File — Created with SAPIEN Technologies PrimalScript 4.1
# NAME: OrgFotos.ps1
# AUTHOR:  Kim Oppalfens,
# DATE  : 12/2/2007
# COMMENT: Helps you organise your digital photos into subdirectory, based on the Exif data
# found inside the picture. Based on the date picture taken property the pictures will be organized into
# c:\organizedfotos\YYYY\DD-MM-YYYY
# ==============================================================================================

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

$Files = Get-ChildItem -recurse -filter *.jpg
foreach ($file in $Files)
  $foo=New-Object -TypeName system.drawing.bitmap -ArgumentList $file.fullname

#each character represents an ascii code number 0-10 is date
#10th character is space separator between date and time
#48 = 0 49 = 1 50 = 2 51 = 3 52 = 4 53 = 5 54 = 6 55 = 7 56 = 8 57 = 9 58 = :
#date is in YYYY/MM/DD format
  $date = $foo.GetPropertyItem(36867).value[0..9]
  $arYear = [Char]$date[0],[Char]$date[1],[Char]$date[2],[Char]$date[3]
  $arMonth = [Char]$date[5],[Char]$dateDevil
  $arDay = [Char]$dateMusic,[Char]$date[9]
  $strYear = [String]::Join(“”,$arYear)
  $strMonth = [String]::Join(“”,$arMonth)
  $strDay = [String]::Join(“”,$arDay)
  $DateTaken = $strDay + “-” + $strMonth + “-” + $strYear
  $TargetPath = “c:\organizedfotos\” + $strYear + “\” + $DateTaken
If (Test-Path $TargetPath)
    xcopy /Y/Q $file.FullName $TargetPath
    New-Item $TargetPath -Type Directory
    xcopy /Y/Q $file.FullName $TargetPath

The post isn’t entirely out-of SystemCenter Scope though, this has freed up quite some time, so I should be able to do some more Sms related posts in the next couple of weeks.

PS: Thomas, for the record, powershell is still just a silly new dos-box. Admitted, a dos-box in which you can do remarkable things every once in a while, but it stays a dos box 😉


“Everyone is an expert at something”
Kim Oppalfens – Sms Expert for lack of any other expertise
Windows Server System MVP – SMS