Skip to content

Instantly share code, notes, and snippets.

@woehrl01
Last active December 9, 2024 14:38
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
@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?

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