Test-Path: In PowerShell prüfen, ob eine Datei existiert

    Fast jede Script-Sprache kann herausfinden, ob eine bestimmte Datei oder ein Verzeichnis vorhanden ist. Dies ist immer dann notwendig, wenn man nicht sicher ist, ob es das in einem Script benötigte Objekt tatsächlich gibt. PowerShell bietet zu diesem Zweck Test-Path, das nicht nur die Existenz einer Datei oder eines Verzeichnisses, sondern auch von Registry-Schlüsseln, Umgebungsvariablen oder Aliases verifizieren kann.

    Aus gutem Grund lassen selbst primitive Batch-Prozessoren wie cmd.exe zu, dass man herausfinden kann, ob eine Datei vorhanden ist. Diese Möglichkeit ist bei Dateioperationen die Voraussetzung für eine defensive Programmierung. Sie vermeidet das Auftreten von Fehlern, indem sie bestimmte Bedingungen vorab berücksichtigt und mit eventuellen Ausnahmen planvoll umgeht.

    Große Verbesserungen gegenüber cmd.exe

    Während sich in cmd.exe eine Datei mit if exist verlässlich nachweisen lässt, muss man für die Überprüfung eines Verzeichnisses schon mit dem Nul-Gerät tricksen (if exist verzeichnis\nul), damit leere Ordner nicht übersehen werden. Auch hier ist PowerShell wesentlich weiter und lässt mit Test-Path alle möglichen Abfragen zu.

    Der einfachste Fall besteht darin, die Existenz einer bestimmten Datei zu prüfen:

    Test-Path docs\readme.txt

    ergibt true, wenn die Datei readme.txt im Verzeichnis docs vorhanden ist. Diese Prüfung ließe sich etwa vor dem Einlesen der Datei mit Get-Content ausführen, um einen Fehler zu vermeiden, wenn es readme.txt nicht gibt:

    if(Test-Path .\Downloads\readme.txt) {Get-Content .\Downloads\readme.txt}

    Existenz mehrerer Dateien abfragen

    Wie in Batch-Dateien kann man auch in PowerShell Wildcards verwenden, um mehrere Dateien mit einem bestimmten Namensmuster zu überprüfen:

    Test-Path docs\*.txt

    Sollen nicht nur Dateien des Typs *.txt, sondern auch PDFs verifiziert werden, dann hilft dabei der Parameter -include. Dieser wirkt als Filter für die im Pfad angegebenen Dateien. Daher ist es wichtig, dass dort nach dem Verzeichnis ein Wildcard angegeben wird:

    Test-Path .\Downloads\* -include *.pdf,*.txt

    Analog dazu ließen sich bestimmte Dateinamen mit Hilfe des Parameters -exclude ausschließen.

    Verzeichnisse überprüfen

    Die Existenz eines Verzeichnisses lässt sich nach dem gleichen Prinzip erfragen, indem man wie bei Dateien dessen Namen übergibt. Auch hier sind Platzhalter zulässig.

    Wenn man nicht sicher sein kann, dass anstatt der gewünschten Datei ein gleichnamiges Verzeichnis existiert (oder umgekehrt), dann kann man Test-Path explizit anweisen, nur nach einem der beiden zu schauen:

    Test-Path docs\readme -pathType container

    Dieser Aufruf interessiert sich nur für readme, wenn es ein Verzeichnis ist. Würde man umgekehrt nur von der Existenz einer Datei erfahren wollen, dann müsste man stattdessen den Parameter -pathType leaf angeben.

    Provider für weitere Datenquellen

    Wie andere Cmdlets, beispielsweise Get-ChildItem, ist auch Test-Path nicht fest mit dem Dateisystem verdrahtet. Vielmehr verrichtet es seine Aufgabe überall dort, wo ihm ein Provider verwertbare Daten zuführt.

    Solche existieren unter anderem für die Registrierdatenbank, Umgebungsvariablen oder Alias-Definitionen. Die Syntax des Aufrufs bleibt dabei immer gleich, nur der Pfad zur Datenquelle muss verschieden notiert werden. Daran kann PowerShell erkennen, welcher Provider zuständig ist.

    Umgebungsvariablen

    Um zu prüfen, ob die Umgebungsvariable temp vorhanden ist, würde man

    Test-Path env:temp

    eingeben. Auch hier ist die Verwendung von Wildcards zulässig.

    Während das Präfix env: den Provider für Umgebungsvariablen auf den Plan ruft, fühlt sich jener für die Registry zum Beispiel bei HKLM: zuständig:

    Test-Path "HKLM:\SOFTWARE\Microsoft\Internet Explorer\Toolbar"

    Auch hier darf neben Wildcards im Pfad auch der Parameter -PathType verwendet werden, um festzustellen, ob ein Ordner oder ein Endknoten vorliegt.

    Existenz eines Alias überprüfen

    Diese Unterscheidung ist aufgrund der flachen Struktur bei Aliases nicht sinnvoll, auch wenn die Verwendung von -PathType zulässig ist:

    Test-Path Alias:\gci

    Auf diese Weise kann man sich in Scripts absichern, ob ein bestimmtes Alias auf dem Rechner definiert ist, bevor man es verwendet. Besser ist es indes, ein bisschen mehr Tipparbeit für den vollständigen Namen eines Befehls in Kauf zu nehmen und dafür ein robusteres Script zu bekommen.

    Keine Kommentare