Powershell: Fenster nach Skriptausführung nicht automatisch schließen

Wenn man ein Powershell-Skript testet und dieses nicht wie gewünscht funktioniert, gibt es nichts nervigeres, als wenn dieses dann einfach geschlossen wird. Die eventuell aufgetretenen Fehlermeldungen kann man dann nicht mehr einsehen. In der Powershell ISE oder in Visual Studio Code ist dies natürlich kein Problem. Aber beim Test auf einem Zielsystem, wo das Skript vielleicht automatisch laufen soll, schon eher. Schon bei Batch-Dateien konnte man sich mit dem Befehl „pause“ am Ende des Skripts behelfen. Dieser funktioniert auch in der Powershell noch. Doch welche Möglichkeiten gibt es noch um das Fenster der Powershell offen zu lassen und welche Vor- oder Nachteile haben diese?

Kurzanleitung:

Wer keine Zeit zum Lesen hat und nur kurz einmalig in seinem Skript dafür sorgen will dass das Fenster offen bleibt schreibt am Ende seines Skriptes einfach „pause“ oder „Read Host“. Bei der Ausführung kann man dann den Output noch in Ruhe sehen und kann das Fenster selber schließen.

 

Lösungsmöglichkeiten direkt im Skript:

Die folgenden Möglichkeiten müssen bei jedem Skript am Ende eingebaut werden um ein automatisches Schließen zu verhindern und dadurch das Powershell-Fenster offen zu lassen:

Wie auch in der CMD funktioniert hier auch der pause-Befehl, allerdings mit einem Unterschied. Soweit ich dies getestet habe, kann man die Unterbrechung nur mit der Enter- und nicht mit einer beliebigen Taste beenden:

 

Wie auch schon in C#-Konsolenprogrammen kann man einfach auf eine beliebige Eingabe des Benutzers warten, als würde man diese in eine Variable einlesen wollen:

Nach der Entgegennahme der eingegebenen Daten folgt kein Befehl mehr und die Konsole schließt sich selbständig.

Dasgleiche Verhalten kann man auch produzieren indem man den alten CMD-Befehl aus dem Powerhsell-Skript aufruft:

 

Natürlich kann man das Skript auch einfach eine extrem lange Zeit pausieren lassen, bevor sich das Fenster von selber schließt:

In diesem Fall kommt aber keine Rückmeldung des Skriptes mehr und man müsste das Konsolenfenster dann selber schließen wenn es frühzeitig beendet werden soll.

 



W E R B U N G

Mit einer Umgebungsvariable auf Nummer sicher gehen?

Sollte man zu der eher vergesslichen Sorte Mensch gehören könnte man Gefahr laufen zu vergessen die letzte Zeile wieder zu entfernen. Wenn man das erfolgreich getestete Skript dann auf Endgeräte kippt, kann man sich schon mal auf Nachfragen einstellen.

Dies kann man beispielsweise durch einen Trick umgehen. Man gestaltet die Skripte so, dass sie nur auf dem Entwicklersystem auf die Benutzereingabe warten. Hierzu kann man z. B. eine Textdatei missbrauchen auf deren Existenz man prüft und nur in diesem Fall die Read-Host-Anweisung ausführt.

Noch cooler geht dies aber mit einer Umgebungsvariable. Hierzu habe ich die Umgebungsvariable „PS_DEV“ erstellt und auf „true“ gesetzt. Der Name ist natürlich völlig egal und kann frei gewählt werden.

Um eine solche Umgebungsvariable anzulegen öffnet man die Systemeigenschaften des Computers und klickt unter dem Reiter „Erweitert“ auf „Umgebungsvariablen“ und kann dann entweder eine Benutzervariable für den angemeldeten Benutzer oder eine Systemvariable für alle Benutezr anlegen:

 

In den Powershell-Skripten kommt dann am Ende die folgende Zeile zum Einsatz:

 

 

Einmalige Lösungsmöglichkeit für die Skriptausführung:

Damit sich das Skript bei der nächsten Ausführung nicht schließt, kann man dieses auch einfach aus der Powershell-Konsole starten. Hierzu öffnet man einfach ein Powershell-Fenster und ruft dann das Skript auf, beispielsweise so:

 

Ebenfalls kann man ein Powershell-Skript auch aus der guten alten Kommandozeile aufrufen und bekommt dann dort die Ausgabe des Powershell-Skriptes angezeigt:

 

Noch einfacher ist allerdings der Aufruf über „Ausführen“ und den „No Exit“-Parameter. Hierzu sucht man im Startmenü nach „Ausführen“ oder drückt gleichzeitig die Windows-Taste + R. Im Fenster gibt man dann folgenden Befehl mit dem Pfad zum auszuführenden Skript ein:

 

 

Geht das auch einfacher? – Verknüpfung und Drag-And-Drop nutzen:

Eine weitere praktische Möglichkeit kann man sich mit Hilfe einer Verknüpfung zur Powershell.exe selber basteln.

Hierzu legt man sich über das Kontextmenü einfach eine neue Verknüpfung an und gibt als Ziel „powershell.exe -NoExit“ an:

Die Verknüpfung kann man so benennen wie man möchte, diese bekommt automatisch das Powershell-Icon:

 

Ein Blick in die Eigenschaften zeigt, dass Windows selbständig den vollständigen Pfad zur Powershell.exe ergänzt hat:

 

Von dem Pfad mit der Versionsnummer 1.0 darf man sich nicht irritieren lassen. Warum auch immer hat Microsoft es versäumt die Versionsnummerierung in der Ordnerstruktur mit hochzuzählen.

Nachdem man diese Verknüpfung erstellt hat kann man seine Skripte einfach per Drag & Drop auf die Verknüpfung ziehen:

 

Danach wird das Powershell-Skript mit der NoExit-Option ausgeführt.

 

Für die ganz Faulen habe ich hier die Verknüpfungsdatei sogar als Download:

 

 

Dauerhafte Lösungsmöglichkeit per Registry-Anpassung:

Wenn einem das alles nicht weit genug geht, kann man sich auch die „Öffnen mit“-Funktion oder die „Ausführen mit Powershell“-Funktion im Kontextmenü umbauen. Hierzu ändert man einfach die entsprechenden Registrierungsschlüssel, die den Aufruf der Powershell.exe vornehmen und ergänzt diese um den „NoExit“-Parameter.

 

„Öffnen mit“-Eintrag anpassen:

Um den Eintrag für die Powershell unter „Öffnen mit“ im Kontextmenü anzupassen öffnet man den Registry-Editor und navigiert unter den Schlüssel „HKEY_CLASSES_ROOT\Applications\powershell.exe\shell\open\command“. Dort ändert man den vorhandenen Registrierungsschlüssel wie folgt ab:

„C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe“ -NoExit „%1“

Achtung: Die Anführungszeichen müssen genauso übernommen werden, sonst funktioniert der Aufruf nicht!

 

Möchte man das ganze wieder rückgängig machen, muss man den Eintrag wieder auf folgenden Default-Wert abändern:

„C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe“ „%1“

 

Schlüssel nicht vorhanden?

Es kann sein, dass der entsprechende Schlüssel noch nicht existiert. Dann hat man noch nie versucht ein Powershell-Skript über die „Öffnen mit“-Funktion aufzurufen. In diesem Fall kann man die entsprechenden Einträge selber erstellen.

Um den Schlüssel anzulegen navigiert man in Regedit unter den Key „HKEY_CLASSES_ROOT\Applications\“ und legt dort den Schlüssel „powershell.exe“ an, in diesem dann den Unterschlüssel „shell“. In diesem wiederum legt man den Schlüssel „open“ an und unter diesem den letzten Unterschlüssel „command“.

Hier ändert man einfach im Unterschlüssel „command“ die Standardzeichenfolge, die dort existiert, ab und fügt den oben gezeigten Befehl für die Ausführung der Powershell ein.

 

Alternativ kann man einfach einmal manuell die „Öffnen mit“-Funktion nutzen und als Anwendung folgenden Pfad angeben:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Danach kann man ebenfalls den Befehl in der Registry anpassen.

 

„Ausführen mit Powershell“-Eintrag anpassen:

Um den Eintrag für die Powershell unter „Ausführen mit Powershell“ im Kontextmenü anzupassen öffnet man den Registry-Editor und navigiert unter den Schlüssel „HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\0\command“. Dort ändert man den vorhandenen Registrierungsschlüssel wie folgt ab:

„C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe“ -NoExit „-Command“ „if((Get-ExecutionPolicy ) -ne ‚AllSigned‘) { Set-ExecutionPolicy -Scope Process Bypass }; & ‚%1′“

Achtung: Auch hier müssen die Anführungszeichen genauso übernommen werden, sonst funktioniert der Aufruf nicht mehr!

 

Möchte man das ganze wieder rückgängig machen, muss man den Eintrag wieder auf folgenden Default-Wert abändern:

„C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe“ „-Command“ „if((Get-ExecutionPolicy ) -ne ‚AllSigned‘) { Set-ExecutionPolicy -Scope Process Bypass }; & ‚%1′“

 

Fazit

Für mich persönlich ist die Verknüpfungs-Variante, die ich sonst nirgendwo im Internet gefunden habe, mit die handlichste Variante. Dies liegt daran, weil man mit dieser nicht Gefahr läuft ein Skript für den Test zu verändern und dann vor der Verteilung dieses Skriptes an Endgeräte zu vergessen den „Debugging“-Modus in Form der letzten Zeile wieder rauszunehmen. Man hält seine Skripte dadurch relativ sauber. Ebenfalls braucht man sich sein System nicht großartig umzukonfigurieren und man braucht auch keinen Umweg über ein weiteres Konsolenfenster oder Kontextmenü zu gehen.

 

Schreibe einen Kommentar