Starten mit der Powershell
29. März 2010Bei der Powershell handelt es sich um das neueste Werkzeug aus dem Haus Microsoft für das Skripting. Mittlerweile ist die Version 2.0 bereits verfügbar und wird sogar bei den neueren Betriebssystemen (etwa bei Windows 7 und Windows Server2008 Release 2) als Standard mitgeliefert.
Generell lässt der Ausdruck Shell bereits vermuten, dass es sich nicht um eine grafische Bedieneroberfläche handelt, sondern um ein Kommandozeilen-Interface (CLI, Command Line Interface). Dabei wird immer eine Befehlszeile eingegeben und dann mit der Return-Taste die Aktion ausgelöst – für Administratoren sicher eine gängige Arbeitsweise.
Ein Mechanismus, bei dem eine Befehlszeile nach der anderen eingegeben wird, erscheint auf den ersten Blick nicht als besonders effizient. Zunächst muss das Kommando korrekt eingegeben werden – und wie schnell hat man sich vor allem bei längeren Befehlszeilen vertippt.
Doch wenn es dann zu einer Art Stapelverarbeitung der Befehle kommt und der Administrator diese Befehlszeilen in einer Datei ablegt und sie so nacheinander ausführt, kann die grafische Benutzerschnittstelle in der Regel in Sachen Effizienz nicht mehr mithalten.
Im einfachsten Fall handelt es sich beim Skripting um eine Anzahl von Kommandos in einer Textdatei, die zeilenweise abgearbeitet werden. Dabei macht die Powershell keine Ausnahme, es muss die Datei mit den Befehlen nur als Textdatei abgelegt werden und zudem die Dateiendung .ps1 verpasst bekommen.
Sicherheit geht vor
Allerdings agiert die Powershell standardmäßig in einem möglichst sicheren Umfeld – und unterscheidet sich damit von früheren Skripting-Hosts auf Windows-Plattformen. Zunächst ist das Ausführen einer Powershell-Befehlsdatei nicht so einfach möglich: Ein doppelter Mausklick aus dem Windows Explorer startet eine Powershell-Befehlsdatei nicht.
Zudem führt die Powershell die Skripts aus dem aktuellen Verzeichnis nicht aus. Doch man muss kein ausgewiesener Powershell-Experte sein, wenn man Powershell-Skripts ausführen möchte. Es sind nur die folgenden Schritte zu absolvieren:
1. Es gilt, die Powershell zu installieren.
2. Anschließend ist die Ausführungsrichtlinie für die Powershell zu setzen.
3. Dann können die Powershell-Skripts gestartet werden – allerdings sollte man sich noch einige wichtige Dinge merken.
Das Installieren der Powershell ist nur auf den älteren Windows-Plattformen nötig. Systeme wie Windows 7 haben diese Umgebung bereits standardmäßig mit dem Betriebssystem installiert. Bei Windows Vista (und frühere Versionen) muss man sich die Software aber per Download (kostenlos) organisieren und installieren.
Bei Windows XP und dem Windows Server 2003 ist zudem noch das Dotnet-Framework in der Version 2.0 von Microsoft nötig. Für die Powershell Version 2.0 ist sogar das Servicepack 1 von Dotnet-Framework 2.0 die Voraussetzung.
Ausführungsrichtlinie für die Powershell setzen
Sicherheit wird bei der Powershell groß geschrieben. Daher dürfen Skripts nur dann zur Ausführung kommen, wenn explizit dazu die Erlaubnis erteilt wird. Dazu besitzt die Powershell vier Ausführungsrichtlinien, die vorgeben, wie Skripts auszuführen sind.
• Restricted: Die Powershell führt überhaupt keine Skripts aus. Das ist die Standardvorgabe für die Powershell.
• AllSigned: Die Powershell startet nur Skripts, die eine digitale Signatur aufweisen. Wenn ein Powershell-Skript von einem Herausgeber signiert wurde, der bisher noch nie in Erscheinung getreten ist, fragt die Powershell nach, ob man diesem Herausgeber vertraut.
• RemoteSigned: Die Powershell wird keine Skripts ausführen, die aus dem Internet geladen wurden – es sei denn, sie verfügen über eine digitale Signatur. Dagegen werden Skripts, die nicht aus dem Internet geladen wurden, gestartet, ohne dass die Powershell nachfragt. Aber auch hier gilt, dass bei einem bisher noch nicht aufgetretenen Herausgeber die Powershell nachfragt, ob er vertrauenswürdig genug ist.
• Unrestricted: Die Powershell ignoriert die digitalen Signaturen, fragt aber nach, ob ein Skript, das aus dem Internet stammt, ausgeführt werden soll.
Um die aktuell eingestellte Ausführungsrichtlinie zu bestimmen, gibt es natürlich auch einen Befehl. Man muss nur das folgende Kommando am Powershell-Prompt eingeben:
Get-ExecutionPolicy
Der Powershell-Prompt sieht in der Regel (wenn das C:-Laufwerk aktuell eingestellt ist) so aus:
PS C:\
Um eine Ausführungsrichtlinie für die Powershell zu setzen, ist ebenfalls ein eigener Befehl einzugeben:
Set-ExecutionPolicy policy
Dabei steht der Parameter policy für einen der vier möglichen Bezeichnungen für die Ausführungsrichtlinie (wie zum Beispiel RemoteSigned).
Allerdings ist zum Umstellen oder Einstellen der Ausführungsrichtlinie die Berechtigungsstufe eines Administrators nötig. Bei Windows Vista (und neueren Systemen) muss man die Powershell mit erhöhter Berechtigungsstufe starten, wenn man Administrator ist und die Benutzerkontensteuerung (UAC, User Access Control) aktiviert ist.
Um die Powershell bei Windows Vista mit den erhöhten Berechtigungen zu starten, muss man mit einem rechten Mausklick auf die Powershell-Verknüpfung gehen und dort den Menüpunkt „Als Administrator ausführen“ wählen.
Wer unter Windows XP oder Windows Server 2003 als normaler Benutzer angemeldet ist, funktioniert eine ähnliche Vorgehensweise: Rechter Mausklick auf die Verknüpfung und dann „Als Administrator ausführen“ – hier sind nur noch die Anmeldeinfos für ein Admin-Konto einzugeben.
Ein wichtiger Ausdruck im Zusammenhang mit der Sicherheit der Powershell ist der Begriff „heruntergeladen aus dem Internet“. Unter Windows bedeutet das, dass im alternativen File Stream die Information vorliegt, dass diese Datei aus dem Internet geladen wurde. Um diese Art der Blockade aufzuheben, muss man einen rechten Mausklick auf die gewünschte ps1-Datei ausführen und dann zu den Eigenschaften der Datei gehen. Hier gibt es dann den Punkt Unlock, auf den zu klicken ist. Damit wird diese Sperrung aufgehoben.
Für den Normalfall gilt die Empfehlung, als Ausführungsrichtlinie „RemoteSigned“ zu wählen. Damit kann man auf seinem Computer Skripts schreiben und sie auch ausführen, ohne dass man dazu ein Zertifikat benötigt. Und die eher gefährlichen Skripts aus dem Internet werden nicht gestartet. Um diese Richtlinie einzustellen, ist der folgende Befehl nötig:
Set-ExecutionPolicy RemoteSigned
Microsoft stellt eine administrative Vorlage (eine adm-Datei) für die Verwaltung der Ausführungsrichtlinie der Powershell zu Verfügung. Dazu gibt es ein GPO (Group Policy Object, Gruppenrichtlinienobjekt), das man über die Website zu den Administratives Templates for Windows Powershell beziehen kann.
Ausführen der Powershell-Skripts
Nachdem die Ausführungsrichtlinie eingestellt ist, kann man die Powershell-Skripts laufen lassen. Dazu muss man ein Powershell-Fenster öffnen und dann den Namen des Skripts (mit oder auch ohne die Erweiterung ps1) eingeben. Dazu sind dann noch die Parameter für das Skript nötig – falls es welch benötigt. Mit der Eingabe von Return wird dann das Skript gestartet. Geht man mit einem doppelten Mausklick auf eine Skriptdatei (mit der Endung ps1), dann wird das Skript im Notepad geöffnet und nicht in der Powershell ausgeführt.
Mit der Powershell 2.0 kommen aber einige Neuerungen ins Spiel. Mit einem rechten Mausklick auf eine ps1-Datei gibt es ab dieser Version die Option im Menü, dass die Datei von der Powershell ausgeführt wird. Doch diese Neuerung sollte man nicht nehmen. Dafür sprechen zwei wichtige Gründe:
• Bei dieser Option schließt sich das Powershell-Fenster sofort, nachdem das Skript beendet ist. Da die meisten Powershell-Skripts nicht so geschrieben sind, dass sie anhalten, wenn sie ihre Arbeit erledigt haben, wird auch die gesamte Ausgabe verschwinden. Dazu gehören auch sämtliche Fehlermeldungen, die im Ablauf des Skripts eventuell anfallen.
• Viele Powershell-Skripts verwenden Kommandozeilen-Parameter, die das Verhalten kontrollieren. Hier gibt es keine Möglichkeit, diese Parameter dem Skript mitzugeben.
Ein weiteres wichtiges Detail betrifft den Startpunkt der Powershell: Sie startet nicht aus dem aktuellen Verzeichnis. Sie verwendet vielmehr einen Pfad. Dabei handelt es sich um eine Komma-begrenzte Liste von Verzeichnissen, die in der Umgebungsvariablen Path abgelegt sind. Windows sucht in diesen Verzeichnissen dann nach ausführbaren Dateien.
Gibt man den Namen eines Skripts (ohne seinen Pfad) ein, und findet Windows diesen Namen nicht in den Verzeichnissen in der Variablen Path, dann wird die Powershell dieses Skript nicht ausführen, selbst wenn es im aktuellen Verzeichnis liegt. Dies ist ein weiterer Aspekt der Sicherheits-Philosophie der Powershell. Denn wenn die Powershell ein Skript im aktuellen Verzeichnis starten würde, wären für Angriffe Tür und Tor geöffnet, bei denen ein böser Bube ein Skript im Verzeichnis ablegt, das denselben Namen hat wie ein gängiges Kommando – aber ganz andere Aktionen ausführt.
Des Weiteren könnte ein Anwender auch ungewollt ein Programm zufällig aufrufen, wenn die Powershell Skripts aus dem aktuellen Verzeichnis starten würde.
Will man aber explizit ein Skript aus dem aktuellen Verzeichnis starten, muss man ein Prefix vor den Namen des Skripts angeben, das die Powershell erkennt. Hierzu eignen sich ein./ oder ein .\ – damit interpretiert die Powershell dann die Angabe richtig.
Angenommen das Verzeichnis C: \Scripts liegt nicht in der Variablen Path und das Skript namens HelloWorld.ps1 liegt in C: \Scripts und die folgenden zwei Befehle werden ausgeführt:
Write-Host "Hello, world"
Read-Host "Press Enter to continue"
Wenn man diese Befehle vom Powershell-Prompt aus startet:
PS C: \> Set-Location C: \Scripts
PS C: \Scripts>HelloWorld
würde die Powershell HelloWorld.ps1 nicht ausführen, auch wenn das aktuelle Verzeichnis C: \Scripts wäre. Die Prompt-Zeichen der Powershell sind nur zu Verdeutlichung hier aufgeführt. Anstelle des zweiten Kommandos müsste man eines der beiden folgenden Kommandos eingeben:
PS: C: \Scripts>.\HelloWorld
PS: C: \Scripts>./HelloWorld
Da die Powershell keine Skripts aus dem aktuellen Verzeichnis ausführt, sollte man sich eine andere Vorgehensweise aneignen: Zuerst ist ein neues Verzeichnis zu erstellen, dann muss man dieses Verzeichnis im Path eintragen und dann sind die Powershell-Skripts in diesem Verzeichnis abzulegen. Damit entledigt man sich der entsprechenden Probleme.
Ein weiteres Detail ist das Behandeln der Leerzeichen in der Powershell. Sie macht das anders, als es bei Cmd.exe gemacht wird. Enthält ein Pfadname Leerzeichen, muss man sie mit doppelten Hochkommata umgeben – um sie in Cmd.exe ausführen zu können. Zum Beispiel würde man für Cmd.exe angeben:
C: \>"C: \Program Files\Scripts\HelloWorld"
Damit startet das Skript C: \Program Files\Scripts\HelloWorld.cmd. Der Einsatz der doppelten Hochkommata, um einen Pfad eines Skripts zu klammern, funktioniert in der Powershell nicht. Denn immer wenn doppelte Hochkommata ins Spiel kommen, behandelt die Powershell den Pfadnamen als einen Ausdruck und nicht als ein Kommando.
Wenn man nur den Namen des Skripts in Hochkommata eingeschlossen eingibt, wie das bei CMD.exe nötig ist, nimmt die Powershell an, dass der Pfadname ein String ist und gibt den Pfadnamen aus anstelle das Skript zu starten. Um dieses Verhalten abzustellen, kann man den Invocation-Operator (das Zeichen &) verwenden. Damit wird dann der eingeklammerte String als ein Kommando ausgeführt:
PS C:\> &"C: \Program Files\Scripts\HelloWorld"
Da man den Operator & und die Anführungszeichen verwenden muss, um ein Skript mit Leerzeichen im Pfadnamen auszuführen, empfiehlt es sich, die Leerzeichen in Skriptnamen möglichst zu vermeiden. Das hat man zumindest dann in der Hand, wenn man selbst Skripts erstellt. Zudem kann man noch ein Verzeichnis vorsehen, in dem man seine Skripts ablegt – und das Verzeichnis sollte möglichst keine Leerzeichen im Pfadnamen aufweisen.