Startseite » wie man » Verwenden einer Stapeldatei, um die Ausführung von PowerShell-Skripts zu vereinfachen

    Verwenden einer Stapeldatei, um die Ausführung von PowerShell-Skripts zu vereinfachen

    PowerShell-Skripts sind aus verschiedenen Gründen, die meist auf die Sicherheit bezogen sind, nicht so einfach portierbar und nutzbar wie Batch-Skripts. Wir können jedoch ein Batch-Skript mit unseren PowerShell-Skripts bündeln, um diese Probleme zu umgehen. Hier zeigen wir Ihnen einige dieser Problembereiche und wie Sie ein Batch-Skript erstellen, um sie zu umgehen.

    Warum kann ich meine .PS1-Datei nicht einfach auf einen anderen Computer kopieren und ausführen??

    Wenn das Zielsystem nicht vorkonfiguriert ist, um die Ausführung beliebiger Skripts mit den erforderlichen Berechtigungen und den richtigen Einstellungen zuzulassen, besteht die Möglichkeit, dass Sie beim Versuch einige Probleme bekommen.

    1. PowerShell ist standardmäßig nicht der .PS1-Dateierweiterung zugeordnet.
      Wir haben dies anfangs in unserer PowerShell Geek School-Serie angesprochen. Windows ordnet .PS1-Dateien standardmäßig Notepad zu, anstatt sie an den PowerShell-Befehlsinterpreter zu senden. Dies verhindert ein versehentliches Ausführen böswilliger Skripts, indem Sie einfach darauf doppelklicken. Es gibt Möglichkeiten, wie Sie dieses Verhalten ändern können, aber wahrscheinlich möchten Sie nicht auf jedem Computer, auf dem Sie Ihre Skripte transportieren, etwas tun - vor allem, wenn sich einige dieser Computer nicht für Sie eignen.
    2. PowerShell lässt standardmäßig keine externe Skriptausführung zu.
      Die Einstellung ExecutionPolicy in PowerShell verhindert standardmäßig die Ausführung externer Skripts in allen Windows-Versionen. In einigen Windows-Versionen erlaubt die Standardeinstellung überhaupt keine Skriptausführung. Wir haben Ihnen gezeigt, wie Sie diese Einstellung ändern können, wie Sie die Ausführung von PowerShell-Skripts unter Windows 7 zulassen. Dies ist jedoch auch etwas, das Sie auf keinem Computer ausführen möchten.
    3. Einige PowerShell-Skripts funktionieren nicht ohne Administratorberechtigungen.
      Selbst wenn Sie mit einem Konto auf Administratorebene arbeiten, müssen Sie immer noch die Benutzerkontensteuerung (UAC) verwenden, um bestimmte Aktionen auszuführen. Wir wollen das nicht deaktivieren, aber es ist immer noch schön, wenn wir es einfacher machen können, damit umzugehen.
    4. Einige Benutzer verfügen möglicherweise über angepasste PowerShell-Umgebungen.
      Sie werden wahrscheinlich nicht oft darauf stoßen, aber wenn Sie dies tun, kann das Ausführen und die Fehlerbehebung Ihrer Skripts ein wenig frustrierend sein. Glücklicherweise können wir dies umgehen, ohne auch dauerhafte Änderungen vorzunehmen.

    Schritt 1: Doppelklicken Sie zum Ausführen.

    Beginnen wir mit dem ersten Problem - .PS1-Dateizuordnungen. Sie können nicht doppelklicken, um .PS1-Dateien auszuführen, aber Sie können eine .BAT-Datei auf diese Weise ausführen. Wir schreiben also eine Batchdatei, um das PowerShell-Skript von der Befehlszeile aus für uns aufzurufen.

    Wir müssen also die Batchdatei nicht für jedes Skript neu schreiben, oder jedes Mal, wenn wir ein Skript verschieben, wird eine selbstreferenzierende Variable verwendet, um den Dateipfad für das PowerShell-Skript zu erstellen. Damit dies funktioniert, muss die Batchdatei im selben Ordner wie Ihr PowerShell-Skript abgelegt werden und denselben Dateinamen haben. Wenn Ihr PowerShell-Skript "MyScript.ps1" heißt, müssen Sie der Batchdatei "MyScript.bat" benennen und sicherstellen, dass sie sich im selben Ordner befindet. Fügen Sie dann diese Zeilen in das Batch-Skript ein:

    @ECHO OFF PowerShell.exe - Befehl "& '% ~ dpn0.ps1" "PAUSE

    Wenn die anderen Sicherheitsbeschränkungen nicht vorhanden wären, würde dies wirklich ausreichen, um ein PowerShell-Skript aus einer Batchdatei auszuführen. In der Tat sind die erste und letzte Zeile hauptsächlich eine Frage der Präferenz - es ist die zweite Zeile, die wirklich die Arbeit erledigt. Hier ist die Aufschlüsselung:

    @ECHO OFF schaltet das Echo des Befehls aus. Dadurch werden Ihre anderen Befehle nur auf dem Bildschirm angezeigt, wenn die Batchdatei ausgeführt wird. Diese Zeile wird durch das Symbol (@) davor verborgen.

    PowerShell.exe - Befehl "& '% ~ dpn0.ps1'" Führt tatsächlich das PowerShell-Skript aus. PowerShell.exe kann natürlich aus einem beliebigen CMD-Fenster oder einer Batch-Datei aufgerufen werden, um die PowerShell wie üblich auf einer leeren Konsole zu starten. Sie können es auch verwenden, um Befehle direkt aus einer Batchdatei auszuführen, indem Sie den Parameter -Command und die entsprechenden Argumente angeben. Die Art und Weise, in der diese Datei verwendet wird, ist die spezielle Variable% ~ dpn0. Aus einer Batchdatei ausgeführt, wird% ~ dpn0 nach Laufwerkbuchstaben, Ordnerpfad und Dateinamen (ohne Erweiterung) der Batchdatei ausgewertet. Da sich die Batchdatei und das PowerShell-Skript im selben Ordner befinden und denselben Namen haben, wird% ~ dpn0.ps1 in den vollständigen Dateipfad des PowerShell-Skripts übersetzt.

    PAUSE pausiert einfach die Batch-Ausführung und wartet auf Benutzereingaben. Dies ist in der Regel hilfreich, wenn Sie am Ende Ihrer Batchdateien arbeiten, sodass Sie die Möglichkeit haben, die Befehlsausgabe zu überprüfen, bevor das Fenster verschwindet. Wenn wir jeden Schritt testen, wird die Nützlichkeit dieses Schrittes deutlicher.

    Die grundlegende Batchdatei ist also eingerichtet. Zu Demonstrationszwecken wird diese Datei als „D: \ Script Lab \ MyScript.bat“ gespeichert und im selben Ordner befindet sich eine „MyScript.ps1“. Mal sehen, was passiert, wenn wir auf MyScript.bat doppelklicken.

    Offensichtlich wurde das PowerShell-Skript nicht ausgeführt, aber das ist zu erwarten - schließlich haben wir nur das erste unserer vier Probleme angesprochen. Es werden jedoch einige wichtige Punkte gezeigt:

    1. Der Fenstertitel zeigt an, dass das Batch-Skript PowerShell erfolgreich gestartet hat.
    2. In der ersten Ausgabezeile wird angezeigt, dass ein benutzerdefiniertes PowerShell-Profil verwendet wird. Dies ist das potentielle Problem Nr. 4, das oben aufgeführt ist.
    3. Die Fehlermeldung zeigt die geltenden Einschränkungen der ExecutionPolicy. Das ist unser Problem # 2.
    4. Der unterstrichene Teil der Fehlermeldung (der durch die PowerShell-Fehlerausgabe nativ erfolgt) zeigt, dass das Batch-Skript das beabsichtigte PowerShell-Skript (D: \ Script Lab \ MyScript.ps1) korrekt anvisiert hat. Wir wissen also zumindest, dass vieles richtig funktioniert.

    Das Profil ist in diesem Fall ein einfaches einzeiliges Skript, das für diese Demonstration verwendet wird, um Ausgaben zu generieren, wenn das Profil aktiv ist. Sie können auch Ihr eigenes PowerShell-Profil anpassen, wenn Sie diese Skripts selbst testen möchten. Fügen Sie Ihrem Profilskript einfach die folgende Zeile hinzu:

    Write-Output 'Benutzerdefiniertes PowerShell-Profil in Kraft!'

    Die ExecutionPolicy auf dem Testsystem ist hier auf RemoteSigned gesetzt. Dies ermöglicht die Ausführung von lokal erstellten Skripts (wie das Profilskript), während Skripts von externen Quellen blockiert werden, sofern sie nicht von einer vertrauenswürdigen Instanz signiert sind. Zu Demonstrationszwecken wurde der folgende Befehl verwendet, um MyScript.ps1 als von einer externen Quelle stammend zu kennzeichnen:

    Add-Content -Path 'D: \ Script Lab \ MyScript.ps1' -Value "[ZoneTransfer] 'nZoneId = 3" -Stream' Zone.Identifier '

    Dadurch wird der alternative Datenstrom "Zone.Identifier" auf MyScript.ps1 festgelegt, sodass Windows den Eindruck hat, dass die Datei aus dem Internet stammt. Es kann leicht mit dem folgenden Befehl rückgängig gemacht werden:

    Clear-Content -Pfad 'D: \ Script Lab \ MyScript.ps1' -Stream 'Zone.Identifier'

    Schritt 2: Ausführen von ExecutionPolicy.

    Die Einstellung "ExecutionPolicy" von CMD oder einem Batch-Skript zu umgehen, ist eigentlich ziemlich einfach. Wir ändern einfach die zweite Zeile des Skripts, um dem Befehl PowerShell.exe einen weiteren Parameter hinzuzufügen.

    PowerShell.exe -ExecutionPolicy Bypass-Befehl "& '% ~ dpn0.ps1'"

    Mit dem Parameter -ExecutionPolicy können Sie die ExecutionPolicy ändern, die verwendet wird, wenn Sie eine neue PowerShell-Sitzung erstellen. Dies wird nicht über diese Sitzung hinaus bestehen bleiben, sodass wir PowerShell jederzeit ausführen können, ohne die allgemeine Sicherheitslage des Systems zu beeinträchtigen. Nachdem wir das behoben haben, wollen wir es noch einmal versuchen:

    Nun, da das Skript ordnungsgemäß ausgeführt wurde, können wir sehen, was es tatsächlich tut. Es lässt uns wissen, dass wir das Skript als Benutzer mit eingeschränkter Lizenz ausführen. Das Skript wird zwar von einem Konto mit Administratorberechtigungen ausgeführt, die Benutzerkontensteuerung stört jedoch. Obwohl Details darüber, wie das Skript den Administratorzugriff prüft, den Rahmen dieses Artikels sprengen würden, ist hier der Code, der zur Demonstration verwendet wird:

    if (([[Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()).. IsInRole ([Security.Principal.WindowsBuiltInRole] "Administrator")) Schreib-Ausgabe 'als Administrator ausgeführt!' else Write-Output 'Running Limited!' Pause

    Sie werden auch bemerken, dass die Skriptausgabe jetzt zwei "Pause" -Operationen enthält - eine aus dem PowerShell-Skript und eine aus der Batchdatei. Der Grund dafür wird im nächsten Schritt deutlicher.

    Schritt 3: Administratorzugriff erhalten.

    Wenn Ihr Skript keine Befehle ausführt, für die eine Erhöhung erforderlich ist, und Sie ziemlich sicher sind, dass Sie sich keine Sorgen darüber machen müssen, dass die benutzerdefinierten Profile eines Benutzers in die Quere kommen, können Sie den Rest davon überspringen. Wenn Sie jedoch einige Cmdlets auf Administratorebene ausführen, benötigen Sie diesen Artikel.

    Leider gibt es keine Möglichkeit, die Benutzerkontensteuerung für eine Erhöhung aus einer Batchdatei oder einer CMD-Sitzung auszulösen. In PowerShell ist dies jedoch mit Start-Process möglich. Bei Verwendung von "-Verb RunAs" in den Argumenten versucht Start-Process, eine Anwendung mit Administratorberechtigungen zu starten. Wenn die PowerShell-Sitzung noch nicht erhöht ist, wird eine Aufforderung zur Benutzerkontensteuerung ausgelöst. Um dies aus der Batch-Datei für den Start unseres Skripts zu verwenden, werden am Ende zwei PowerShell-Prozesse erzeugt - einer startet Start-Process und der andere Start wird mit Start-Process gestartet, um das Skript auszuführen. Die zweite Zeile der Batchdatei muss folgendermaßen geändert werden:

    PowerShell.exe -Command "& Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -Datei" "% ~ dpn0.ps1" "' -Verb RunAs"

    Wenn die Batchdatei ausgeführt wird, stammt die erste Ausgabezeile aus dem PowerShell-Profilskript. Wenn Start-Process versucht, MyScript.ps1 zu starten, erscheint eine Eingabeaufforderung.

    Nachdem Sie durch die UAC-Eingabeaufforderung geklickt haben, erscheint eine neue PowerShell-Instanz. Da es sich hierbei um eine neue Instanz handelt, wird die Profilskriptnachricht natürlich wieder angezeigt. Dann wird MyScript.ps1 ausgeführt und wir sehen, dass wir uns tatsächlich in einer erhöhten Sitzung befinden.

    Und das ist auch der Grund, warum wir hier zwei Pausen haben. Wenn das für das PowerShell-Skript nicht vorhanden wäre, würden wir niemals die Ausgabe des Skripts sehen. Das PowerShell-Fenster würde einfach auftauchen und verschwinden, sobald das Skript ausgeführt wurde. Und ohne die Pause in der Batchdatei können wir nicht feststellen, ob beim ersten Start von PowerShell Fehler aufgetreten sind.

    Schritt 4: Benutzerdefinierte PowerShell-Profile umgehen.

    Lassen Sie uns jetzt diese böse benutzerdefinierte Profilbenachrichtigung loswerden, oder? Dies ist zwar kaum lästig, aber wenn das PowerShell-Profil eines Benutzers die Standardeinstellungen, Variablen oder Funktionen in einer Weise ändert, die Sie möglicherweise mit Ihrem Skript nicht erwartet haben, kann dies sehr mühsam sein. Es ist viel einfacher, Ihr Skript ohne das Profil vollständig auszuführen, so dass Sie sich keine Gedanken darüber machen müssen. Dazu müssen Sie nur noch die zweite Zeile der Batchdatei noch einmal ändern:

    PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Datei" "% ~ dpn0.ps1" "-Verb RunAs"

    Durch Hinzufügen des Parameters -NoProfile zu beiden Instanzen von PowerShell, die vom Skript gestartet werden, wird das Profilskript des Benutzers in beiden Schritten vollständig umgangen, und unser PowerShell-Skript wird in einer ziemlich vorhersagbaren Standardumgebung ausgeführt. Hier können Sie sehen, dass in keiner der erzeugten Muscheln ein benutzerdefiniertes Profil angezeigt wird.

    Wenn Sie in Ihrem PowerShell-Skript keine Administratorrechte benötigen und Sie Schritt 3 übersprungen haben, können Sie auf die zweite PowerShell-Instanz verzichten und die zweite Zeile Ihrer Stapeldatei sollte folgendermaßen aussehen:

    PowerShell.exe -NoProfile -ExecutionPolicy Bypass-Befehl "& '% ~ dpn0.ps1'"

    Die Ausgabe sieht dann so aus:

    (Natürlich können Sie auch für Skripts, die kein Administrator sind, an diesem Punkt auf eine Skriptendepause in Ihrem PowerShell-Skript verzichten, da alles im selben Konsolenfenster erfasst wird und dort von der Pause am Ende von gehalten wird die Batch-Datei trotzdem.)

    Abgeschlossene Batchdateien.

    Abhängig davon, ob Sie Administratorberechtigungen für Ihr PowerShell-Skript benötigen oder nicht (und Sie sollten sie wirklich nicht anfordern, wenn dies nicht der Fall ist), sollte die endgültige Batchdatei wie folgt aussehen.

    Ohne Admin-Zugriff:

    @ECHO OFF PowerShell.exe -NoProfile -ExecutionPolicy Bypass-Befehl "& '% ~ dpn0.ps1'" PAUSE

    Mit Administratorzugang:

    @ECHO OFF PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Datei" "% ~ dpn0.ps1" "' -Verb RunAs" PAUSE

    Denken Sie daran, die Batchdatei im selben Ordner wie das PowerShell-Skript abzulegen, für das Sie sie verwenden möchten, und geben Sie ihr den gleichen Namen. Unabhängig davon, auf welches System Sie diese Dateien übertragen, können Sie Ihr PowerShell-Skript ausführen, ohne sich mit den Sicherheitseinstellungen des Systems herumschlagen zu müssen. Sie können diese Änderungen sicherlich jedes Mal manuell vornehmen, was Ihnen jedoch den Ärger erspart, und Sie müssen sich nicht darum kümmern, die Änderungen später rückgängig zu machen.


    Verweise:

    • Ausführen von PowerShell-Skripts aus einer Batchdatei - Daniel Schroeders Programmierblog
    • Überprüfen auf Administratorberechtigungen in PowerShell - Hey, Scripting Guy! Blog