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 es läuft im Hintergrund der Timer ab. Man müsste das Konsolenfenster dann selber schließen, wenn es frühzeitig beendet werden soll.

 



W E R B U N G

Vor- und Nachteile

Diese Befehle sind alle relativ einfach zu verwenden.Das ist aber auch der einzige Vorteil.

Der Nachteil an all diesen Befehlen ist nämlich, dass sie in den Skripten zum Testen hinzugefügt und letzt endlich wieder entfernt werden müssen.

Ebenfalls kann man diese Befehle alle vergessen, sofern man das Powershell-Fenster nach Durchlauf des Skriptes noch nutzen möchte. Dies könnte der Fall sein, wenn man beispielsweise ein Skript geschrieben hat, das zu einer Datenbank oder einem Exchange-Server oder etwas anderem eine Verbindung aufbaut.

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 beispielsweise die Read-Host-Anweisung ausführt.

Auswerten einer Umgebungsvariable in der PowershellNoch 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 Benutzer anlegen:

Konfigurieren einer Umgebungsvariable per GUI

 

In den Powershell-Skripten kommt dann am Ende z. B. 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 manuell 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 Ausführen-Fenster gibt man dann folgenden Befehl mit dem Pfad zum auszuführenden Skript ein:

 

Für einen Einzeiler kann man auch folgenden Weg mit Hilfe eines an die PS-Sitzung übergebenen “Commands” nutzen:

 

Vor- und Nachteile

Der Vorteil an diesen Varianten bzw. an der Nutzung des “No Exit”-Parameters ist außerdem, dass man in der Powershell-Konsole nach Durchlauf des Skriptes noch manuell Befehle absetzen kann. Das ist besonders praktisch wenn das Skript z. B. zum Aufbau einer Verbindung zu einer Datenbank, zu einem Exchange-Server oder Azure genutzt wird und danach manuell auf dieser Grundlage weitergearbeitet werden soll. Allerdings muss man für solche Fälle aufpassen und z. B. mit globalen Variablen arbeiten um auf Werte aus dem schon abgeschlossenen Skript zurückgreifen zu können. Hierfür definiert man eine Variable z. B. so:

Nervig ist allerdings, dass man das Skript über Umwege aus einer anderen Powershell- oder CMD-Sitzung aufrufen muss.

Wenn du noch nicht so fit im Umgang mit der Powershell bist, gibt es hier einen Anfängerkurs* mit 23 Lektionen, Testfragen, Skriptbeispielen, Handouts und mehr als 4 Stunden Videomaterial!
 

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:

Verknüpfung zur Powershell mit NoExit-Parameter erstellen

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

Verknüpfung zur Powershell mit NoExit-Parameter

 

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

 

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. (Verwirrender geht es kaum… )

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

Drag&Drop eines Powershell-Skriptes auf die Verknüpfung

 

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 vorbereitet:

 

 

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:

Powershell in der AUswahl als "Öffnen mIt"-EintragUm 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:

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

Konfiguration des "Öffnen mit"-Eintrags in der Registry

 

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

 

Nicht verwechseln: Die Anpassung bzw. Erstellung  dieses “Öffnen mit”-Eintrags beeinflusst nicht das Öffnen der .ps1-Datei per Doppelklick auf die Datei selber oder per Kontextmenü auf “Öffnen”. Dazu gibt es weiter unten noch einen eigenen Punkt.

 

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

Den "Öffnen mit"-Eintrag per GUI erstellen

Danach kann man ebenfalls den Befehl in der Registry anpassen.

 

“Ausführen mit Powershell”-Eintrag anpassen:

"Mit Powershell ausführen" im Kontextmenü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:

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

Konfiguration des "Ausführen mit Powershell"-Eintrags in der Registry

 

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

 

“Öffnen” und Doppelklick anpassen:

Man kann natürlich auch den “Öffnen”-Befehl abändern, der auch für den Doppelklick herangezogen wird. Dieser ist normalerweise auf das Notepad eingestellt. Das Skript wird dadurch zur Sicherheit standardmäßig nicht ausgeführt, wenn man einen Doppelklick auf die .ps-Datei macht. Wer das ändern möchte kann natürlich auch den entsprechenden Registry-Schlüssel “HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command” verändern. Hierzu den vorhandenen Eintrag bzgl. der Notepad.exe einfach durch den bereits beschriebenen Command ersetzen:

Konfiguration des "Öffnen"-Eintrags in der Registry

 

Eigener Kontextmenüeintrag

Wer angeben möchte kann sich auch direkt einen eigenen Eintrag im Kontextmenü erstellen. Hierzu muss man unter “HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\”  einen eigenen Schlüssel mit der gleichen Struktur anlegen wie z. B. für “Open”. Darunter befindet sich dann der Schlüssel “command” und in diesem fügt man in der Standardzeichenfolge wieder diesen Aufruf ein:

Eigener Menüeintrag im KontextmenüIch habe diesen Eintrag bei mir “Mit PS ausführen + NoExit” genannt. Aussehen tut das ganze dann wie folgt:

 

Konfiguration eines eigenen Kontextmenü-Eintrags in der Registry

Will man den Eintrag im Kontextmenü doch nicht mehr haben kann man den Schlüssel in der Registry einfach wieder löschen.

 

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.

 

Weitere interessante Artikel zur Windows Powershell:

Welche PowerShell-Version habe ich? – PowerShell-Version anzeigen
Was ist PowerShellCore? Windows PowerShell unter Linux und MacOS?
Powershell und CMD: Clear um Konsole zu leeren?
Powershell: Sudo-Befehl wie unter Linux nutzen für Administratorrechte?
COM-Port eines Geräts ändern per Powershell
CMD/Powershell: Ping-Ergebnis mit Errorlevel auswerten
Powershell: Netzwerkadapter-Konfiguration ändern (IP-Adresse, Gateway, DNS, DHCP)
Powershell-Skript als Benutzer-Anmeldeskript in einer Domäne nutzen?
Powershell: Fenster nach Skriptausführung nicht automatisch schließen
Powershell: UTF8-Problem beim Export
XML-Bearbeitung mit Powershell
Replace und Escaping in Powershell
MessageBox mit Powershell auf anderen Computern anzeigen
While- und Until-Schleifen in PowerShell und Batch
Einfaches inkrementelles Backup mit Powershell
Einfache Außer-Haus-Sicherung mit Powershell
Schnittstelle von XML zu MS-SQL mit Powershell realisieren
Powershell: Automatische Anwendungssteuerung
Macht die ExecutionPolicy für Powershell-Skripte Sinn?
Wiederkehrende E-Mail-Abwesenheitsnotiz für Outlook mit Powershell
HyperV-Netzwerkadapter per Powershell umbenennen und entfernen
Powershell: DELL Service Tags auslesen
Powershell-Backup-Skript für den Thunderbird-Profilordner
Download-Skript in Powershell
Einfache Powershell-Skripte
Java-Anwendungen über CMD oder Powershell starten
Pfad im Explorer schneller kopieren – auch als vollständigen UNC-Pfad
Windows 11: Startmenü anpassen, klassische Taskleiste, links ausrichten
Wie lange läuft mein PC schon? – PC Laufzeit auslesen unter Windows 10
Windows 10: Standorttyp des Netzwerks ändern
Windows Server 2016: WSUS startet nicht vernünftig
 

2 Kommentare

  1. Avatar
    Hibr Dezember 15, 2021 11:25 am  Antworten

    Sehr guter und v.a. umfangreicher Artikel, besonders zur Powershell.

    • Tobias Langner
      Tobias Langner Dezember 15, 2021 11:28 pm  Antworten

      Hallo Hibr,

      vielen Dank. Es gibt mit Sicherheit noch mehr Möglichkeiten. Falls ich noch über eine stolpere füge ich sie noch hinzu 😉

      Viele Grüße
      Tobias

Schreibe einen Kommentar