To get all of this extended metadate you could use the function below.
You can give it the path to a single file, or the path to a folder where the files are.
function Get-MetaData {
[CmdletBinding()]
[OutputType([Psobject[]])]
Param (
# Path can be the path to a folder or the full path and filename of a single file
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
[string]$Path,
# Pattern is unused if Path is pointing to a single file
[Alias('Filter')]
[string]$Pattern = '*.*',
[Alias('Indices')]
[int[]]$Properties = 1..500,
# Recurse is unused if Path is pointing to a single file
[switch]$Recurse,
[switch]$IncludeEmptyProperties
)
$item = Get-Item -Path $Path -ErrorAction SilentlyContinue
if (!$item) { Write-Error "$Path could not be found."; return }
if (!$item.PSIsContainer) {
# it's a file
$files = @($item)
$Path = $item.DirectoryName
}
else {
# it's a folder
$files = Get-ChildItem -Path $Path -Filter $Pattern -File -Recurse:$Recurse
}
$shell = New-Object -ComObject "Shell.Application"
$objDir = $shell.NameSpace($Path)
foreach($file in $files) {
$objFile = $objDir.ParseName($file.Name)
$mediaFile = $objDir.Items()
foreach($index in $Properties) {
$name = $objDir.GetDetailsOf($mediaFile, $index)
if (![string]::IsNullOrWhiteSpace($name)) {
$value = $objDir.GetDetailsOf($objFile, $index)
if (![string]::IsNullOrWhiteSpace($value) -or $IncludeEmptyProperties) {
[PsCustomObject]@{
Path = $file.FullName
Index = $index
Property = $name
Value = $value
}
}
}
}
}
# clean-up Com objects
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objFile)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objDir)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
You can of course play around with the different parameters the function can take like -Pattern '*.mp4'
to only list properties for mp4 files or add switch -IncludeEmptyProperties
to also list properties that exist for that file type, but have no value for the specified file.
With parameter Properties
you can give the function an array of int32 values of the property indices to return. If you leave that open, the function tries to get all properties from index 1 to index 500 (if available).
Most of the interesting property indices can be found at:
- audio/video files:
0,1,2,3,4,5,9,11,12,13,14,15,16,17,18,19,20,21,22,26,27,28,36,164,165,194,213,220,223,237,243
- font files:
0,1,2,3,4,5,20,21,25,33,34,164,165,166,196,310
- image files:
0,1,2,3,4,5,9,11,31,164,165,174,175,176,177,178,194,196
Use it like this:
$result = Get-MetaData -Path '<pathToTheFile_OR_pathToTheFolder>'
# output to GridView
$result | Out-GridView
# output to CSV file
$result | Export-Csv -Path '<pathToTheOutput.csv>' -NoTypeInformation