Skip to content

Instantly share code, notes, and snippets.

@woehrl01
Last active April 5, 2025 23:43
Show Gist options
  • Save woehrl01/5f50cb311f3ec711f6c776b2cb09c34e to your computer and use it in GitHub Desktop.
Save woehrl01/5f50cb311f3ec711f6c776b2cb09c34e to your computer and use it in GitHub Desktop.
# based on https://gallery.technet.microsoft.com/scriptcenter/Get-FileMetaData-3a7ddea7
function Get-FileMetaData
{
<#
.SYNOPSIS
Get-FileMetaData returns metadata information about a single file.
.DESCRIPTION
This function will return all metadata information about a specific file. It can be used to access the information stored in the filesystem.
.EXAMPLE
Get-FileMetaData -File "c:\temp\image.jpg"
Get information about an image file.
.EXAMPLE
Get-FileMetaData -File "c:\temp\image.jpg" | Select Dimensions
Show the dimensions of the image.
.EXAMPLE
Get-ChildItem -Path .\ -Filter *.exe | foreach {Get-FileMetaData -File $_.Name | Select Name,"File version"}
Show the file version of all binary files in the current folder.
#>
param([Parameter(Mandatory=$True)][string]$File = $(throw "Parameter -File is required."))
if(!(Test-Path -Path $File))
{
throw "File does not exist: $File"
Exit 1
}
$tmp = Get-ChildItem $File
$pathname = $tmp.DirectoryName
$filename = $tmp.Name
$hash = @{}
try{
$shellobj = New-Object -ComObject Shell.Application
$folderobj = $shellobj.namespace($pathname)
$fileobj = $folderobj.parsename($filename)
for($i=0; $i -le 294; $i++)
{
$name = $folderobj.getDetailsOf($null, $i);
if($name){
$value = $folderobj.getDetailsOf($fileobj, $i);
if($value){
$hash[$($name)] = $($value)
}
}
}
}finally{
if($shellobj){
[System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$shellobj) | out-null
}
}
return New-Object PSObject -Property $hash
}
Export-ModuleMember -Function Get-FileMetadata
@BUZZARDGTA
Copy link

thank you very much!

@cquresphere
Copy link

Is there any way to make attribute names in PSCustomObject immutable (I mean universal despite different local culture and language settings on the host)?

@JWheelMaker
Copy link

Love you <3

@MicheleJohl
Copy link

I had a bit of a nightmare with the date parsing for the "Date Taken" due to hidden Unicode values.

Can see the Unicode in VS Code:
image

So, I wrote a complimentary Parse-Date function :

function Parse-Date {
    param (
        [string]$DateString
    )

    # Clean up the date string by removing any invisible characters
    $DateString = $DateString.Trim() -replace [char]8206, "" -replace [char]8207, ""

    # Output the cleaned date string for debugging
    Write-Host "Cleaned date string: '$DateString'"

    # Regular expression pattern to match the date format
    $regexPattern = '^(?<day>\d{2})/(?<month>\d{2})/(?<year>\d{4}) (?<hour>\d{2}):(?<minute>\d{2})$'

    if ($DateString -match $regexPattern) {
        $day = $matches['day']
        $month = $matches['month']
        $year = $matches['year']
        $hour = $matches['hour']
        $minute = $matches['minute']

        # Construct the DateTime object
        $parsedDate = Get-Date -Year $year -Month $month -Day $day -Hour $hour -Minute $minute
        return $parsedDate
    } else {
        throw "Unable to parse the date string: '$DateString'"
    }
}

@jfrmilner
Copy link

Another approach to fixing the malformed DateTime's returned ie "Content created". Replace all non digits and use DateTime.ParseExact Method:

Get-FileMetaData -File 'C:\MyExcelFile.xlsx' | Select-Object -Property Name, @{Name="Content created";Expression={[DateTime]::ParseExact(($_.'Content created' -replace "\D"), "ddMMyyyyHHmm", $null)}}

@songyongshun
Copy link

Is there a way to modifiy the metadata of file?

@MicheleJohl
Copy link

@songyongshun There isn’t a dedicated PowerShell cmdlet that I know of for editing file metadata natively. PowerShell relies on either the Shell.Application COM object or on third-party utilities (e.g., ExifTool). The example below uses the Shell.Application COM object, which is bundled with Windows, but it’s not an official PowerShell cmdlet.

More details on what you trying to edit?

Function Set-FileMetaData {
    param(
        [Parameter(Mandatory=$true)]
        [string]$FilePath
        [Parameter(Mandatory=$true)]
        [int]$PropertyIndex,
        [Parameter(Mandatory=$true)]
        [string]$NewValue
    )

    $shell = New-Object -ComObject Shell.Application
    $folder = $shell.Namespace((Split-Path $FilePath -Parent))
    $file = $folder.ParseName((Split-Path $FilePath -Leaf))
    $folder.SetDetailsOf($file, $PropertyIndex, $NewValue)
}

#To Use
Set-FileMetaData -FilePath "C:\Path\To\File.mp3" -PropertyIndex 21 -NewValue "The New Title"

@carrzkiss
Copy link

The output gives the following.
LRM
When you do
Get-FileMetaData -File "W:\Photos\Canon 800D\2019\2019_12_08\IMG_1302_1.JPG" | Select "Date taken", etc...
The output has Unicode characters U+200E and U+200F
LRM-RLM
Copy and Pasted into Notepad++ shows LRM and RLM
Notepad++ LRM-RLM

How can we eliminate this so the output is clean without these Unicode characters?

@carrzkiss
Copy link

carrzkiss commented Apr 5, 2025

Have an update for your code.
replace line 52
#$hash[$($name)] = $($value)
with this
$hash[$($name)] = $($value) -replace "\u200E","" -replace "\u200F",""
This will get rid of the Unicode characters U+200E and U+200F.

For anyone interested.
I have the updated code on my site now.
PowerShell Get-FileMetaData - Remove Unicode Characters from Output

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment