colinardo
Goto Top

Erweiterte Dateieigenschaften mit Powershell-Funktion abfragen

back-to-topBeschreibung
Folgende Powershell-Funktion extrahiert die Erweiterten Dateieigenschaften wie man sie 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
function Add-ExtendedFileProperties{
 <#
     .SYNOPSIS
        Fügt erweiterte Eigenschaften von Dateien an das Objekt in der Pipline hinzu
     .DESCRIPTION
        Extrahiert erweiterte Eigenschaften von Dateien wie z.B. Exif-Daten, Musik- bzw. Filmdetails
     .EXAMPLE 
            Get-ChildItem "C:\Temp" | Add-ExtendedFileProperties -PropertyExtended "Bildhöhe","Bildbreite","Datenrate" | ft Name,Bildhöhe,Bildbreite,Datenrate  
            Fügt alle nur die Eigenschaften "Bildhöhe","Bildbreite","Datenrate" als zusätzliche Spalten dem Objekt in der Pipline hinzu  
     .EXAMPLE
            Get-ChildItem "C:\Temp" | Add-ExtendedFileProperties | fl *  
            Fügt alle verfügbaren erweiterten Eigenschaften dem Objekt in der Pipline hinzu
     .PARAMETER PropertyExtended
        Mit diesem Parameter geben sie eine Komma-Separierte Liste von Eigenschaften an welche sie erhalten möchten.
            -PropertyExtended "Bildhöhe","Bildbreite","Bitrate"  
#>
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        $fileItem,
        [String[]] $PropertyExtended = "ALL"  
    )
    begin
    {
        $shellObject = New-Object -Com Shell.Application
        $itemProperties = $null
    }
    process
    {
        if($fileItem.PsIsContainer)
        {
            $fileItem
            return
        }
        $directoryName = $fileItem.DirectoryName
        $filename = $fileItem.Name

        $folderObject = $shellObject.NameSpace($directoryName)
        $item = $folderObject.ParseName($filename)

        if(-not $itemProperties)
        {
            $itemProperties = @{}
            $counter = 0
            $columnName = ""  
            if ($PropertyExtended -eq "ALL"){  
                 #get all properties
                do {
                    $columnName = $folderObject.GetDetailsOf($folderObject.Items, $counter)
                    if($columnName) { $itemProperties[$counter] = $columnName }
                    $counter++
                }while($columnName)
            }else{
                #get user defined properties
                do {
                    $columnName = $folderObject.GetDetailsOf($folderObject.Items, $counter)
                    foreach($name in $PropertyExtended){
                        if ($columnName.toLower() -eq $name.toLower()){
                            $itemProperties[$counter] = $columnName
                        }
                    }
                    $counter++
                }while($columnName)
            }
        }

        foreach($itemProperty in $itemProperties.Keys)
        {
            $fileItem | Add-Member NoteProperty $itemProperties[$itemProperty] `
                $folderObject.GetDetailsOf($item, $itemProperty) -ErrorAction `
                SilentlyContinue
        }
        $fileItem
    }
}
back-to-topParameter der Funktion
Parameter Beschreibung
-PropertyExtended [Optional] Namen der zu extrahierenden erweiterten Eigenschaften werden in einer Komma-Separierten Liste angegeben(bsp: "Bildhöhe","Bildbreite")

back-to-topBeispielhafte Anwendung
back-to-topBeispiel 1: Alle verfügbaren Erweiterten Dateieigenschaften von Dateien ausgeben
Get-ChildItem "C:\Ordner" | Add-ExtendedFileProperties | select *
back-to-topBeispiel 2: Nur bestimmte Eigenschaften von Dateien ausgeben
Get-ChildItem "C:\Ordner" | Add-ExtendedFileProperties -PropertyExtended "Bildhöhe","Bildbreite" | select FullName,Bildhöhe,Bildbreite
back-to-topHinweise
Man sollte wenn möglich immer die zu extrahierenden Eigenschaften mit angeben, weil dies den Vorgang erheblich beschleunigt wenn nicht alle Eigenschaften extrahiert werden müssen.

Viel Spaß damit face-smile

Grüße @colinardo

Content-ID: 223082

Url: https://administrator.de/contentid/223082

Ausgedruckt am: 23.11.2024 um 08:11 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