EXIF data with PowerShell (Part 3)
Building off of my first two posts on interacting with EXIF metadata using PowerShell, reading the EXIF tag value and reading Lat and Long, I left off with calling Get-FileContents
to create a file handle to a pass to Get-ExifContents
and Get-ExifCoordinates
and then return a custom PowerShell object that can be interacted with to output data to either the screen or to a CSV file. Below is a screenshot of calling the script with a JPG given as input.
So the script is called and a file is passed as a named parameter to script. The first lines of the script will accept parameters from the PowerShell prompt and override the default values.
1 2 3 4 5 6 7 8 |
param( [string]$file = $false, [string]$exportcsv = $false, ) # Loads the System.Drawing DLL for usage Add-Type -Assembly System.Drawing |
To handle the System.Drawing
DLL not being correctly loaded when calling it in Get-FileContents
I called it at the beginning of the script. I set those two values as false so that I can respond to them in conditional statements further in the script. The next block of code in the script, Write-Results
is a custom function to output the EXIF contents to the screen.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Function Write-Results{ param($label, $value) # Writes the property label to the output without a new line Write-Host "${label}: " -NoNewline if ($value -like "<empty>"){ # if the EXIF data is not there writes the text in green text Write-Host $value -ForegroundColor DarkGreen } else { # If there is EXIF data write the data in red text Write-Host $value -ForegroundColor DarkRed } } |
By setting the “foreground” color, aka the text, it allows the output to be easily glanced at and determine if there is metadata associated to the tag. After that, the user is prompted to input the file path if the variable $file
was not set when the script was called and is still $false
. The next line creates an Array List, a PowerShell object that is a mutable list, that will be used to store the metadata objects as returned after parsing the JPGs. Next, using the .NET framework, the script checks to see if the $file
variable is a directory. If it’s a directory, it creates a list of files in the directory and calls Get-FileContents
for each JPG and stores the PowerShell object in the array list. And if it’s not a directory, it will add the output of Get-FileContents
to the array list.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# Prompts the user for the file path if it was not given upon invocation if (!$file){ $file = Read-Host -Prompt "Path to photo to inspect" } $exportArray = [System.Collections.ArrayList]@() $isDir = (Get-Item $file) -is [System.IO.DirectoryInfo] # Write-Output "isDir: $isDir" if ($isDir){ $fileList = (Get-ChildItem $file).fullname foreach($childFile in $fileList){ $ext = (Get-ChildItem $childFile).extension if($ext -ne ".jpg"){ Write-Output "$childFile is not a jpg, skipping" continue } $obj = Get-FileContents($childFile) $exportArray.add($obj) | Out-Null } } else { $ext = (Get-ChildItem $file).extension if($ext -notlike ".jpg"){ Write-Output "$file does not have .jpg extension" exit } $obj = Get-FileContents($file) $exportArray.add($obj) | Out-Null } |
At this point, we now have an Array list of PowerShell objects containing the metadata for the JPGs that we can interact with. I piped $exportArray.add($obj)
to Out-Null
so that the object will not be output to the screen when called. The only thing still required to mark the script complete at this point before adding the ability to remove the metadata from the JPGs is to either print the output to the screen or export it to a CSV. The following code is pretty much self-explanatory to finish this script up. When exporting the Array list, if desired, the first row in the CSV is headers containing the keys identified in the PS object. If exporting to a CSV was not specified the program will then output the results to the screen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
if ($exportcsv){ $exportArray | Export-Csv -NoTypeInformation -Append $exportcsv } if ($exportcsv -eq $false){ # Writes the results to the screen for veiwing foreach($obj in $exportArray){ Write-Host Picture: $obj.file Write-Results -label "Camera Maker" -value $obj.cameramaker Write-Results -label "Camera Model" -value $obj.cameramodel Write-Results -label "Software Version" -value $obj.softwareversion Write-Results -label "Time Taken" -value $obj.datetaken Write-Results -label "Latitude" -value $obj.latitude Write-Results -label "Longitude" -value $obj.longitude Write-Results -label "Altitude" -value $obj.altitude } } |
Stay tuned for part 4 where I remove the metadata and post the full script.