Skip to content

How to Extract Metadata (EXIF, Properties) from a File in Batch Script

Learn how to extract file metadata (EXIF, EXIF data, document properties, audio tags) using PowerShell and Batch scripts for automated file sorting, archiving, and organization.

Extracting metadata, such as the "Date Taken" from a photograph (EXIF data), the "Author" of a Word document, or the "Bitrate" of an MP3 file, is invaluable for automated file sorting and archiving. Batch scripts do not natively decode file headers. However, Windows has a built-in mechanism via PowerShell and the Shell.Application COM object to read file properties.

In this guide, we will demonstrate how to extract metadata from files using a PowerShell bridge.

Method 1: The PowerShell Bridge (Shell COM Object)

The Windows Shell indexes files and exposes hundreds of properties. By calling the Shell.Application namespace via PowerShell from your Batch script, you can retrieve any attribute.

Implementation Script

@echo off
setlocal enabledelayedexpansion

:: Target File Details
set "targetFolder=C:\Users\Public\Pictures"
set "targetFile=vacation.jpg"

:: Check if file exists
if not exist "!targetFolder!\!targetFile!" (
    echo [ERROR] File not found: !targetFolder!\!targetFile!
    pause
    exit /b 1
)

echo Extracting properties for: !targetFile!...
echo.

:: Extracting EXIF "Date Taken" (Property ID 12)
for /f "usebackq delims=" %%A in (`
    powershell -NoProfile -Command ^
        "$sh = New-Object -ComObject Shell.Application; " ^
        "$folder = $sh.Namespace('!targetFolder!'); " ^
        "$file = $folder.ParseName('!targetFile!'); " ^
        "$val = $folder.GetDetailsOf($file, 12); " ^
        "if ($val) { $val -replace '[^\x20-\x7E]','' } else { 'N/A' }"
`) do set "dateTaken=%%A"

:: Extracting Image "Dimensions" (Property ID 31)
for /f "usebackq delims=" %%A in (`
    powershell -NoProfile -Command ^
        "$sh = New-Object -ComObject Shell.Application; " ^
        "$folder = $sh.Namespace('!targetFolder!'); " ^
        "$file = $folder.ParseName('!targetFile!'); " ^
        "$val = $folder.GetDetailsOf($file, 31); " ^
        "if ($val) { $val -replace '[^\x20-\x7E]','' } else { 'N/A' }"
`) do set "dimensions=%%A"

echo ==========================================
echo DATE TAKEN:  !dateTaken!
echo DIMENSIONS:  !dimensions!
echo ==========================================
pause

Extracting Multiple Properties Efficiently

To avoid launching PowerShell multiple times (each call adds ~200–500ms overhead), extract all properties in a single call:

@echo off
setlocal enabledelayedexpansion

set "targetFolder=C:\Users\Public\Pictures"
set "targetFile=vacation.jpg"

if not exist "!targetFolder!\!targetFile!" (
    echo [ERROR] File not found.
    pause
    exit /b 1
)

:: Extract multiple properties in a single PowerShell call
set "propIndex=0"
for /f "usebackq delims=" %%A in (`
    powershell -NoProfile -Command ^
        "$sh = New-Object -ComObject Shell.Application; " ^
        "$folder = $sh.Namespace('!targetFolder!'); " ^
        "$file = $folder.ParseName('!targetFile!'); " ^
        "foreach ($id in @(0,1,2,3,4,12,31)) { " ^
        "    $name = $folder.GetDetailsOf($null, $id) -replace '[^\x20-\x7E]',''; " ^
        "    $val = $folder.GetDetailsOf($file, $id) -replace '[^\x20-\x7E]',''; " ^
        "    if (-not $val) { $val = 'N/A' }; " ^
        "    Write-Output \"$name=$val\" " ^
        "}"
`) do (
    echo %%A
)

pause

Method 2: Basic File Properties (Native PowerShell)

If you only need basic file system properties (CreationTime, LastWriteTime, Length) instead of EXIF/Document properties, you don't need the COM object:

@echo off
setlocal enabledelayedexpansion

set "filePath=C:\Temp\document.txt"

if not exist "!filePath!" (
    echo [ERROR] File not found: !filePath!
    pause
    exit /b 1
)

for /f "usebackq delims=" %%A in (`
    powershell -NoProfile -Command "(Get-Item -LiteralPath '!filePath!').LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss')"
`) do set "lastWrite=%%A"

for /f "usebackq delims=" %%A in (`
    powershell -NoProfile -Command "(Get-Item -LiteralPath '!filePath!').Length"
`) do set "sizeBytes=%%A"

echo File Size:     !sizeBytes! bytes
echo Last Modified: !lastWrite!
pause

Why Extract Metadata?

  1. Photo Organization: Automatically renaming .jpg files to include their EXIF "Date Taken" (e.g., 2024-05-12_Image01.jpg) rather than the date they were copied to the disk.
  2. Audio Archiving: Sorting MP3 files into folders based on the "Artist" or "Album" metadata rather than random filenames.
  3. Document Auditing: Extracting the true "Author" or "Company" tag embedded inside Word documents or PDFs.

Common Shell Property IDs

When using the Shell.Application COM object (Method 1), the property ID numbers vary slightly depending on the Windows version, but these are standard on Windows 10/11:

ID Property File Types
0 Name All
1 Size All
2 Item type All
3 Date modified All
4 Date created All
12 Date taken Photos
13 Contributing artists Audio
14 Album Audio
27 Length (duration) Video, Audio
31 Dimensions Images

Important Considerations

Conclusion

Combining Batch logistics with PowerShell's Shell COM object enables robust metadata extraction. By reading EXIF data, audio tags, and document properties directly from the command line, you elevate your file management scripts from simple name-based sorters to intelligent, content-aware archivers. This capability is indispensable for digital asset management and automated organization.

Navigation