Where-Object: Daten filtern in PowerShell


    Tags:

    Filter in PowerShellDas Ergebnis eines Cmdlets ist oft eine große Sammlung von Objekten, von denen man jedoch meistens nur einige braucht. Als Filter dient in diesen Fällen das Cmdlet Where-Object (Alias Where oder ?), an das man den Output über eine Pipe weiterleitet. Seit PowerShell 3.0 unterstützt es eine vereinfachte Syntax.

    Liest man mit Hilfe von PowerShell bestimmte Systeminformationen aus, beispielsweise eine Liste aller Dateien in einem Verzeichnis, der aktuell ausgeführten Prozesse oder der im Active Directory angelegten User, dann erhält man meistens ein Array mit zahlreichen Elementen zurück. Möchte man sämtliche Objekte anzeigen und bloß einzelne Eigenschaften auswählen, dann kann man dies mit Select-Object tun.

    Where mit Bedingungen

    Will man das Ergebnis jedoch auf jene Objekte einschränken, auf die bestimmte Kriterien zutreffen, dann ist Where-Object das Mittel der Wahl. Sein Aufruf erfordert die Angabe einer Bedingung, die man mit Hilfe von Vergleichsoperatoren formuliert.

    Wenn man etwa alle Dateien im aktuellen Verzeichnisbaum anzeigen möchte, die im Jahr 2014 erstellt oder aktualisiert wurden, dann kann man dies mit folgendem Befehl erledigen:

    gci -r | Where {$_.LastWriteTime -gt "01.01.2014"}

    Die von Get-ChildItem (Alias gci) zurückgegebene Liste von Dateiobjekten gelangt an Where-Object, wo $_ das aktuelle Pipeline-Objekt repräsentiert. Dessen Eigenschaft LastWriteTime wird darauf geprüft, ob es größer als der 1.1.2014 ist. Es sollten schließlich nur solche Dateien im Ergebnis auftauchen, die nach diesem Datum geändert wurden.

    Komplexe Bedingungen

    Der Script-Block in den geschweiften Klammern kann auch komplexere Ausdrücke enthalten, die mehrere Bedingungen umfassen:

    gci -r | Where {$_.LastWriteTime -gt "01.01.2014" -and $_.length -lt 1GB}

    In diesem Beispiel würde zusätzlich geprüft, ob eine Datei kleiner als 1GB ist.

    Beide bis jetzt vorgestellten Aufrufe verwenden eine Schreibweise, in der die Bedingung als Script-Block notiert ist und das aktuelle Objekt über $_ referenziert wird.

    Vereinfachte Syntax

    Seit PowerShell 3.0 besteht jedoch die Möglichkeit zur Verwendung einer einfacheren Syntax. Das obere Beispiel würde man damit so schreiben:

    gci -r | Where LastWriteTime -gt "01.01.2014"

    Hier entfallen somit die geschweiften Klammern sowie die Variable für das aktuelle Pipeline-Objekt, die Angabe der Eigenschaft alleine reicht.

    Die vereinfachte Syntax für Where-Object lässt sich nur für einfache Bedingungen nutzen.

    Diese Schreibweise ist aber nur für einfache Bedingungen zulässig, sobald mehrere mit einem logischen Operator verknüpft werden, produziert PowerShell eine Fehlermeldung. Das zweite Beispiel, das zusätzlich die Dateigröße prüft, ließe sich also nicht in der einfachen Syntax darstellen.

    Bevorzugt an der Quelle filtern

    Where-Object ist nicht die einzige und nicht immer die beste Möglichkeit, um Daten zu filtern. Es setzt voraus, dass ein vorhergehender Befehl alle zurückgegebenen Objekte auf den lokalen Rechner herunterlädt und diese dann über eine Pipe an den Filter gelangen.

    Wenn Cmdlets die gewünschten Daten bereits an der Quelle ausfiltern können, dann ist dies ein günstigeres Vorgehen. Das trifft zum Beispiel auf solche zu, die das Active Directory oder Remote-Systeme über WMI abfragen können. So liefert etwa Get-ADUser nur solche User-Objekte, die den Kriterien im Argument -Filter entsprechen. Ein Auslesen aller User, um sie anschließend lokal mit Where-Object mit bestimmten Bedingungen zu vergleichen, wäre im Vergleich dazu ineffizient.

    Keine Kommentare