Dateiattribute anzeigen und bearbeiten mit PowerShell


    Tags: ,

    Dateiattribute im ExplorerUnter dem alten Kommando­interpreter cmd.exe kann man mit dem dir-Befehl und dem Dienst­programm attrib.exe die Attribute von Dateien recht unkompliziert ausgeben, filtern oder ändern. PowerShell hat dafür eigene Mecha­nismen, die aber etwas auf­wändiger sind und sich daher primär für Scripts eignen.

    Zu den gängigsten Aufgaben in Zusammen­hang mit File-Attributen zählt das Filtern von Dateien anhand der Eigen­schaften Archiv, Nur-Lesen, System oder Versteckt. Obwohl Windows auf NTFS-Partitionen eine ganze Reihe von Datei­attributen kennt, sind es meistens diese vier, welche man setzen oder entfernen möchte.

    Die gesamte Liste an unterstützten Attributen kann man sich mit

    [enum]::GetValues([system.io.fileattributes])

    ausgeben lassen. Diese Namen braucht man nachher, wenn man die Attribute ändern möchte.

    Liste mit den Namen aller möglichen Dateiattribute

    Nicht alle dieser Eigen­schaften lassen sich schreiben, das gilt beispiels­weise für Directory.

    Attribute mit Get-ChildItem anzeigen

    Während der dir-Befehl unter cmd.exe die Attribute von Dateien nicht anzeigt, scheinen diese beim PowerShell-Gegenstück Get-ChildItem (Alias gci oder dir) in der Ausgabe unter der Spalte Mode auf. Es beschränkt sich dabei jedoch auf die vier oben genannten plus das Ver­zeichnis­attribut.

    Die Dateiattribute zeigt Get-ChildItem unter Mode an

    Dafür macht es der alte dir-Befehl sehr einfach, Dateien nach Attributen zu filtern. Ein

    dir /ars

    listet alle Dateien mit den Attributen Readonly und System auf. Für diese Aufgabe muss man unter PowerShell mehr Aufwand betreiben.

    Zum einen sollte man Get-ChildItem mit dem Schalter -Force aufrufen, um sicher­zustellen, dass auch jene Dateien angezeigt werden, die als Hidden oder System gesetzt wurden. Zum anderen muss man die Ausgabe durch einen Filter mit Where-Object (Alias ?) schicken:

    dir -Force | ? mode -like *r*

    Für das Prüfen des bloßen Schreibschutzes steht zudem eine separate Eigenschaft namens IsReadOnly zur Verfügung. Folgender Befehl würde True zurückgeben, wenn das Attribut ReadOnly gesetzt ist:

    (dir -Force .\test.txt).IsReadOnly

    Will man dieses Verfahren auf mehrere Dateien anwenden, dann könnte man dies so tun:

    (dir -Force *.txt) | select Name, IsReadOnly

    Filter für mehrere Attribute

    Komplizierter wird es, wenn man nicht nur nach ReadOnly, sondern nach mehreren Attributen gleichzeitig fragen möchte. Hier müsste man alle möglichen Kombinationen aus Attribut­kürzel und Binde­strichen mit dem like-Operator untersuchen, zum Beispiel "*a--s" für Archive und ReadOnly.

    Dateien anhand von Attributen filtern über die Eigenschaft Mode

    Will man alle Dateien finden, die zum Beispiel das Attribut Hidden oder System gesetzt haben, dann bietet sich der Einsatz von -Match und einem regulären Ausdruck an:

    dir -Force | ? mode -match '(r|h)'

    Attributes-Eigenschaft nutzen

    Die Abfrage der Eigenschaft Mode hat nicht nur den Nachteil, dass man die Zeichenkette aus den Anfangs­buchstaben der Attributnamen untersuchen muss, sondern dass sie wie erwähnt nur 5 Attribute berücksichtigt.

    Daher kann man alternativ auf die Eigenschaft Attributes zurückgreifen:

    dir -Force *.txt | Format-Table -AutoSize Name, Attributes

    Die Eigenschaft Attributes von Dateisystemobjekten ausgeben und formatieren

    Dieser Befehl gibt den vollständigen Namen der Attribute aus, und der folgende zeigt alle versteckten Dateien mit der Endung .txt an:

    gci -Force *.txt | ? Attributes -like "*Hidden*"

    Zudem kann man darauf Filter anwenden, ohne sich um die Reihenfolge der Attribute kümmern zu müssen, wie das beim Zugriff auf die Zeichenkette Mode der Fall ist:

    dir -Force *.txt | ?{$_.Attributes -like "*Hid*" -and $_.Attributes -like "*Read*"}

    Da der Filter einen Ausdruck mit zwei Bedingungen enthält, lässt sich die vereinfachte Notation für Where-Object nicht mehr verwenden. Vielmehr muss man den Ausdruck in geschweifte Klammern setzen und auf die Variable $_ zurück­greifen. Im Vergleich zu einem herkömmlichen

    dir /arh *.txt

    ist die PowerShell-Version schon sehr komplex und für den Einsatz in einer interaktiven Shell eigentlich zu umständlich. Allerdings lassen sich damit alle Attribute abfragen, nicht nur die gängigen fünf.

    Ein weiteres Cmdlet, das Dateiattribute ausgeben kann, ist Get-ItemProperty:

    Get-ItemProperty *.txt | ft -Auto -Property Name, Attributes

    Der Nachteil dieses Kommandos besteht aber darin, dass es keine Dateien berücksichtigt, bei denen die Attribute System oder Hidden gesetzt sind.

    Dateiattribute ändern

    Um die Attribute von Dateien zu bearbeiten, weist man der Attributes-Eigenschaft ein Array zu, bestehend aus den Attributnamen:

    (dir -Force .\test.txt).Attributes = "Archive", "NotContentIndexed", "System"

    Wie man hier sieht, muss man jedes Mal sämtliche Attribute zuweisen. Es ist nicht möglich, einfach nach dem Muster von

    attrib +r test.txt

    etwa ein einzelnes Attribut zu den bestehenden hinzu­zufügen.

    Mehrere Dateien ändern

    Noch umständlicher wird dieses Verfahren, wenn man die Attribute mehrerer Files ändern möchte. Dann müsste man über alle Dateien mit einer Schleife iterieren (% als Alias für foreach):

    dir -Force *.txt | %{$_.Attributes = "Hidden, ReadOnly"}

    Dateiattribute an mehrere Files in einer Schleife zuweisen.

    Eine Alternative stellt hier das Cmdlet Set-ItemProperty dar, das die Attribute mehrerer Dateien auf einmal setzen kann:

    Set-ItemProperty *.txt -Name Attributes -Value "System, Archive"

    Allerdings leidet es wie sein Gegenspieler Get-ItemProperty unter der Einschränkung, dass es keine Dateien ändern kann, die als System oder als versteckt markiert sind.

    Täglich Know-how für IT-Pros mit unserem Newsletter

    Wir ver­wenden Ihre Mail-Adresse nur für den Ver­sand der News­letter.
    Es erfolgt keine per­sonen­be­zogene Auswertung.

    Bild von Wolfgang Sommergut

    Wolfgang Sommergut hat lang­jährige Erfahrung als Fach­autor, Berater und Kon­ferenz­sprecher zu ver­schie­denen Themen der IT. Da­ne­ben war er als System­ad­mi­ni­stra­tor und Con­sultant tätig.
    // Kontakt: E-Mail, XING, LinkedIn //

    Verwandte Beiträge

    Weitere Links

    2 Kommentare

    Kann es sein das hier "Dir" Anstatt Set-item bzw. Get-item benutzt wurde (versehentlich?)

    Bild von Wolfgang Sommergut

    "Dir" ist ein vordefiniertes Alias für Get-ChildItem. Für das CLI ok, aber für Scripts sollte man Aliase vermeiden.