colinardo

Erweiterte Dateieigenschaften mit Powershell-Funktion abfragen


back-to-topBeschreibung


Mit der folgenden Powershell-Funktion lassen sich die erweiterten Dateieigenschaften auslesen wie man sie sich z.B. in den Eigenschaften einer Datei auf dem Tab Details anzeigen lassen kann.

131fbbdb55b84fc7773369dcd415d120

Das können z.B. solche Dinge wie EXIF-Details, Bildbreite, Bildhöhe, Bitrate, etc sein. Die Funktion fügt diese Eigenschaften den Datei-Objekten in der Pipeline als zusätzliche Eigenschaften hinzu. Beispiele dazu findet ihr weiter unten.

back-to-topPowershell-Funktion : Add-ExtendedFileProperties


 <#
     .SYNOPSIS
        Fügt erweiterte Eigenschaften von Dateien an das Filesystem-Objekt in der Pipline hinzu
     .DESCRIPTION
        Extrahiert erweiterte Eigenschaften von Dateien wie z.B. Exif-Daten, Musik- bzw. Filmdetails
     .EXAMPLE 
            Get-ChildItem "C:\Temp" -File -Filter *.jpg | Add-ExtendedFileProperties -PropertyExtended System.Image.BitDepth,System.Image.HorizontalSize,System.Image.VerticalSize | select-object Name,System.Image.Bitdepth,System.Image.HorizontalSize,System.Image.VerticalSize  
            
            Fügt nur die Eigenschaften für Farbtiefe, Breite und Höhe der Bilder als zusätzliche Eigenschaften den Objekten in der Pipline hinzu.
            Verfügbare CanonicalNames für den Parameter "PropertyExtended" lassen sich hier nachschlagen:  
            => https://learn.microsoft.com/en-us/windows/win32/properties/props
     .PARAMETER PropertyExtended
        Mit diesem Parameter geben sie eine Komma-Separierte Liste von Eigenschaften an welche sie erhalten möchten.
            -PropertyExtended System.Image.HorizontalSize,System.Image.VerticalSize
#>
function Add-ExtendedFileProperties {
    param(
        [Parameter(mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)][Alias("Fullname")][string[]]$path,  
        [Parameter(mandatory=$true)][ValidateNotNullOrEmpty()][string[]]$PropertyExtended
    )
    begin {
        $shellObject = New-Object -ComObject Shell.Application
    }
    process {
        foreach($file in $path){
            $fsitem = Get-Item -LiteralPath $file
            if(!$fsitem.PsIsContainer){
                $shellitem = $shellObject.NameSpace($fsitem.DirectoryName).ParseName($fsitem.Name)
                foreach($prop in $PropertyExtended){
                    $fsitem | Add-Member -Membertype Noteproperty -Name $prop -Value $shellitem.ExtendedProperty($prop)
                }
            }
           $fsitem
        }
    }
}

back-to-topParameter der Funktion


Parameter Beschreibung
PropertyExtended CanonicalNames oder GUIDs der zu extrahierenden erweiterten Eigenschaften werden in einer Komma-Separierten Liste angegeben. Verfügbare CanonicalNames für den Parameter "PropertyExtended" lassen sich hier nachschlagen => Windows Properties
path Pfad(e) von Dateien, entweder übergeben über die Pipeline mittels Get-ChildItem oder als String-Array

back-to-topBeispielhafte Anwendung


back-to-topErweiterte Eigenschaften einer Reihe von Dateien über die Pipeline ausgeben


Get-ChildItem "C:\Ordner" -File -Filter *.jpg | Add-ExtendedFileProperties -PropertyExtended System.Image.HorizontalSize,System.Image.VerticalSize | select-object FullName,System.Image.HorizontalSize,System.Image.VerticalSize  

back-to-topErweiterte Eigenschaften einer/mehrerer Datei(en) mittels direkter Pfadangabe ausgeben


Add-ExtendedFileProperties -Path "D:\datei1.jpg","D:\datei2.jpg" -PropertyExtended System.Image.Dimension | select-object FullName,System.Image.Dimension  

Die verfügbaren CanonicalNames lassen sich auf folgender Webseite sortiert nach Dateikategorie nachschlagen:
Windows Properties

Viel Spaß damit face-smile

Grüße @colinardo

Datum Update
07.05.2025Funktion von der Abfrage mittels "GetDetailsOf" auf "ExtendedProperty" und der Angabe der CanonicalNames der Eigenschaften umgestellt. Damit sind die Abfragen sprachunabhängig und zuverlässiger.
Auf Facebook teilen
Auf X (Twitter) teilen
Auf Reddit teilen
Auf Linkedin teilen

Content-ID: 223082

Url: https://administrator.de/tutorial/erweiterte-dateieigenschaften-mit-powershell-funktion-abfragen-223082.html

Ausgedruckt am: 29.05.2025 um 01:05 Uhr

rubberman
rubberman 30.11.2013 aktualisiert um 14:08:47 Uhr
Goto Top
Hallo colinardo,

sehr schöne Funktion!

Vor ein paar Jahren hatte ich mich auch schon mal intensiver damit beschäftigt. Um eine bestimmte Eigenschaft auszulesen, hatte ich die ExtendedProperty Methode ausgegraben, bei der man mit dem Namen der Eigenschaft direkt den entsprechenden Wert zurück bekommt.
Scripting mit Shell-Objekten ist und bleibt aber ein Alptraum. Mit GetDetailsOf bekommst du die deutschen Bezeichnungen, ExtendedProperty musst man hingegen mit den englischen Bezeichnungen füttern. So zieht sich das durch die gesamte Arbeit mit Shell-Objekten.
Hast du eine Idee, wie man aus diesem multilingualen Mist irgend etwas brauchbares machen kann? Ich meine kann man das MUI für ein Script irgendwie ausschalten oder irgendwie festlegen mit welcher Sprache man arbeiten möchte?

Grüße
rubberman
colinardo
colinardo 30.11.2013 um 15:10:22 Uhr
Goto Top
Zitat von @rubberman:
Hast du eine Idee, wie man aus diesem multilingualen Mist irgend etwas brauchbares machen kann? Ich meine kann man das MUI für ein Script irgendwie ausschalten oder irgendwie festlegen mit welcher Sprache man arbeiten möchte?
Hallo rubberman,
wüsste ich jetzt nicht, das es solch eine Funktion gäbe. Mit entsprechendem Aufwand und der Hinterlegung von den gängigsten Sprachen mit dessen Übersetzungen der Eigenschaften in Arrays ließe sich das aber bewerkstelligen. Das tu ich mir jetzt aber nicht an face-wink

Grüße Uwe
rubberman
rubberman 30.11.2013 um 20:11:14 Uhr
Goto Top
Hallo colinardo,

ja nee, eine Übersetzungstabelle würde ich auch nicht erstellen. Gibt's ja offensichtlich auch schon (wenn auch in anderer Form). Alles was man da selbst übersetzt und einbindet ist redundant, potenziell fehlerbehaftet und beim nächsten Windowsupdate vielleicht schon veraltet. Ich hatte nur gehofft, dass sich da eine Einstellung oder eine Methode findet ... nicht lebensnotwendig natürlich face-wink

Grüße
rubberman
colinardo
colinardo 26.09.2021 aktualisiert um 12:32:42 Uhr
Goto Top
Zitat von @rubberman:
Scripting mit Shell-Objekten ist und bleibt aber ein Alptraum. Mit GetDetailsOf bekommst du die deutschen Bezeichnungen, ExtendedProperty musst man hingegen mit den englischen Bezeichnungen füttern. So zieht sich das durch die gesamte Arbeit mit Shell-Objekten.
Hast du eine Idee, wie man aus diesem multilingualen Mist irgend etwas brauchbares machen kann?

Servus @rubberman,
zwar schon ziemlich angestaubt der Thread hier, aber der Thread war mir noch irgendwie im Gedächtnis geblieben, und damit die Nachwelt auch noch was davon hat. Du kennst das sicherlich auch schon.

Der Methode ExtendedProperty lässt sich eine formatID und propID im GUID Format übergeben womit man sprachunabhängig arbeiten kann da die GUIDs über die Windows-Versionen hinweg wohl eindeutig sind.
Das sieht dann so aus (Beispiel für die FileVersion einer Datei )
$shell = New-Object -Com  Shell.Application
$shell.NameSpace("D:\Ordner").ParseName("datei.exe").ExtendedProperty("{0CEF7D53-FA64-11D1-A203-0000F81FEDEE} 4")  
Also die formatID in geschweiften Klammern und mit Blank dahinter die propID.

Die GUIDs für die formatID und die daugehörigen propIDs lassen sich hier nachschlagen
https://docs.microsoft.com/en-us/windows/win32/properties/props

Des weiteren lässt sich dort auch der CanonicalName der Eigenschaft einsetzen der ebenfalls sprachunabhänig ist
$shell = New-Object -Com  Shell.Application
$shell.NameSpace("D:\Ordner").ParseName("datei.exe").ExtendedProperty("System.FileVersion")  

Grüße Uwe
rubberman
rubberman 26.09.2021 aktualisiert um 13:18:47 Uhr
Goto Top
Hallo Uwe,

hab gerade mal in meiner Snippet Sammlung gestöbert. Das letzte mal dass ich mich damit beschäftigt hatte war 2016. Weder "formatID propID" noch "CanonicalName" ist da irgendwie dabei. Vermutlich war es einfach zu abwegig einfach einen String aus den IDs zu machen. Und den CanonicalName hatte ich wohl als Klasse/Namespace.Eigenschaft interpretiert und auch da nicht mal probiert als String zu übergeben.
Danke auf jeden Fall für das Update!

Grüße
Steffen
GoSher
GoSher 05.05.2025 um 15:08:28 Uhr
Goto Top
Hallo colinardo,

sehr schöne Funktion! Leider funktioniert die Pipe mit der Funktion bei mir nicht. Würde mir bei Videos enorm helfen.

Get-ChildItem "D:\Temp" | C:\Scripts\Add-ExtendedFileProperties.ps1 | select *		Nichts passiert - auch keine Fehlermeldung.  
Get-ChildItem "D:\Temp" | select *							Funktioniert normal mit Anzeige der Dateien  

Hab Win11 und folgendes probiert:
Set-PSBreakpoint -Script C:\Scripts\Scripts\Add-ExtendedFileProperties.ps1 -Variable fileItem
... ohne Reaktion

Bin bei Powershell noch ein Neuling - wie kann ich den Fehler finden?

LG GoSher
colinardo
colinardo 05.05.2025, aktualisiert am 07.05.2025 um 10:07:00 Uhr
Goto Top
Hallo @GoSher,
Deine Verwendung ist leider nicht korrekt. Entweder du packst die Funktion mit in den Kopf deiner Skripte, oder lagerst die Funktion in ein separates Skript oder Modul aus und lädst dieses vor der Pipe. Im einfachsten Fall bei dir also folgendermaßen
# Skript/Funktion in die Session laden (Bitte den Punkt beachten!)
."C:\Scripts\Add-ExtendedFileProperties.ps1"  
# Eigenschaften abfragen
Get-ChildItem -Path "D:\Ordner" -File -Filter *.jpg | Add-ExtendedFileProperties -PropertyExtended System.Image.Dimension | select Fullname,System.Image.Dimension  

Als Modul wäre es am sinnigsten dann hast du es in jeder Session automatisch verfügbar wenn du es öfters benötigst (sofern du es in eines der Modul-Verzeichnisse deines OS legst (Anzeigen mittels $env:PSModulePath))
https://learn.microsoft.com/de-de/powershell/module/microsoft.powershell ...

# Module in die Session laden (manuell nur nötig wenn Skript nicht in einem Modulverzeichnis liegt)
Import-Module "C:\Scripts\Add-ExtendedFileProperties.ps1"  
# Eigenschaften abfragen
Get-ChildItem -Path "D:\Ordner" -File -Filter *.jpg | Add-ExtendedFileProperties -PropertyExtended System.Image.Dimension | select Fullname,System.Image.Dimension  

Gruß @colinardo
GoSher
GoSher 06.05.2025 aktualisiert um 18:22:35 Uhr
Goto Top
Hallo colinardo,

Vielen Dank. Mit Deinen Tipps habe ich die Funktion jetzt lauffähig bekommen.

Aber Windows überrascht mich wieder einmal. Die Attribute Breite, Höhe (oder Bildbreite, Bildhöhe, Height, Width) lassen sich bei z.B. *.jpg oder *.mp4 partout nicht anzeigen. Obwohl "Abmessungen" angezeigt wird:

Get-ChildItem "D:\Temp\*.jpg" -File | Add-ExtendedFileProperties -PropertyExtended "Abmessungen","Breite" | select FullName,Abmessungen,Breite,LastAccessTime  

FullName             Abmessungen Breite LastAccessTime
--------             ----------- ------ --------------
D:\Temp\herz_weich.jpg ‪720 x 576‬        06.05.2025 17:02:00

Da ich in VB.Net die function GetDetailsOf() bereits nutze - dort bekomme ich Breite und Höhe aufgelistet. Auszug :
...
           'Alle verfügbaren Tags in Textdatei eintragen  
           Dim objShell = CreateObject("shell.application")  
           Dim objFolder = objShell.Namespace(Path.GetDirectoryName(Datei))
           If (objFolder IsNot Nothing) Then
               Dim objFolderItem = objFolder.ParseName(Path.GetFileName(Datei))
               If (objFolderItem IsNot Nothing) Then
                   ' there are a varying number of entries depending on the OS  
                   ' 34 min, W7=290, W8=309 with some blanks  
                   ' this should get up to 310 non blank elements  
                   Do
                       Wert = objFolder.GetDetailsOf(objFolderItem, I)
                       If String.IsNullOrEmpty(Wert) = False Then
                           Textzeile = "" & Str(I) & "=" & objFolder.GetDetailsOf(Nothing, I) & "=" & Wert  
                           'Debug.Print(Textzeile)  
                           file.WriteLine(Textzeile)
                       End If
                       I += 1
                   Loop Until I > 310
                   'Do Until String.IsNullOrEmpty(Wert) Or I > 310  
                   'Loop  
               End If
           End If

Ausgabe des o.g. VB.Net-Codes:
0=Name=herz_weich.jpg
1=Größe=23,2 KB
2=Elementtyp=IrfanView JPG File
3=Änderungsdatum=02.12.2005 21:32
4=Erstelldatum=06.05.2025 17:02
5=Letzter Zugriff=06.05.2025 17:02
6=Attribute=A
9=Erkannter Typ=Bild
...
31=Abmessungen=‪720 x 576‬
...
175=Horizontale Auflösung=‎150 dpi
176=Breite=‎720 Pixel
177=Vertikale Auflösung=‎150 dpi
178=Höhe=‎576 Pixel
190=Ordnername=Temp
191=Dateispeicherort=D:\Temp
...

Das passt auch zur Anzeige im Windows-Explorer s.u.

In deiner Komplett-Variante kommen Breite und Höhe bei meinen Dateien gar nicht vor. Versteh ich nicht.
Get-ChildItem "D:\Temp\*.jpg" -File | Add-ExtendedFileProperties | select *  

Ausserdem: Sind GetDetailsOf() bei Powershell und VB.Net unter Windows nicht identisch?
2025-05-06 18_21_35-eigenschaften von herz_weich
colinardo
colinardo 06.05.2025 aktualisiert um 19:40:56 Uhr
Goto Top
Die Funktion hat nun schon ein paar Jahre auf dem Buckel und die IDs sind OS übergreifend nicht unbedingt gleich oder überhaupt vorhanden, besser ist es gleich die Methode zu nutzen die ich in einem Kommentar weiter oben genannte habe, diese verwendet die genormten Windows CanonicalNames oder GUIDs mit der Eigenschaft "ExtendedProperty", zudem ist diese Methode Sprachunabhängig nutzbar.

Ich schreibe die Funktion bei Zeiten noch mit der Methode um.

VG @colinardo
GoSher
GoSher 06.05.2025 um 20:05:04 Uhr
Goto Top
Kann deine Funktion aktualisiert werden auf die CanonicalName ".ExtendedProperty("System.FileVersion")" ?
Sonst ist diese alte Version ja wg. "babylon. Sprachverwirrung" nur noch von historisch begrenztem Nutzen. Schade.
colinardo
colinardo 06.05.2025, aktualisiert am 07.05.2025 um 09:50:48 Uhr
Goto Top
Zitat von @GoSher:

Kann deine Funktion aktualisiert werden auf die CanonicalName ".ExtendedProperty("System.FileVersion")" ?
Ja, wie oben bereits geschrieben, aktualisiere ich sie und den Artikeltext die nächsten Tage wenn die Zeit es bei mir zulässt.
Bis dahin kannst du ja die Codeschnipsel aus dem o.g. Kommentar dafür nutzen.

Ein Quicky Zweizeiler bspw. für die Breite und Höhe der Bilder erledigt dir das auch eigentlich ohne extra "Funktion" über ein select-object.
$shell = New-Object -Com  Shell.Application
Get-ChildItem "D:\Ordner" -File -Filter *.jpg | select Fullname,@{n='Breite';e={$shell.NameSpace($_.DirectoryName).ParseName($_.Name).ExtendedProperty("System.Image.HorizontalSize")}},@{n='Höhe';e={$shell.NameSpace($_.DirectoryName).ParseName($_.Name).ExtendedProperty("System.Image.VerticalSize")}}  
Die Liste der verfügbaren Properties(CanonicalNames oder GUIDs) ist ja oben verlinkt.

Insofern braucht ein Powersheller eigentlich keine extra Funktion mehr für die paar Zeichen mit der Methode 😉

-edit 07.05.2025- Funktion und Beschreibung dazu wurde im Artikel oben aktualisiert.