Connect with us

Wie man

So verwenden Sie eine Batchdatei, um die Ausführung von PowerShell-Skripten zu vereinfachen

So verwenden Sie eine Batchdatei, um die Ausführung von PowerShell-Skripten zu vereinfachen

Aus mehreren Gründen, hauptsächlich aus Sicherheitsgründen, sind PowerShell-Skripts nicht so einfach zu portieren und zu verwenden wie Batch-Skripts. Wir können jedoch ein Batch-Skript mit unseren PowerShell-Skripten 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 so vorkonfiguriert wurde, dass beliebige Skripts mit den erforderlichen Berechtigungen und den richtigen Einstellungen ausgeführt werden können, treten bei diesem Versuch möglicherweise Probleme auf.

  1. PowerShell ist standardmäßig nicht mit der Dateierweiterung .PS1 verknüpft.
    Wir haben dies zunächst in unserer PowerShell Geek School-Reihe erwähnt. Windows ordnet dem Editor standardmäßig .PS1-Dateien zu, anstatt sie an den PowerShell-Befehlsinterpreter zu senden. Dies soll verhindern, dass böswillige Skripte versehentlich ausgeführt werden, indem Sie einfach darauf doppelklicken. Es gibt Möglichkeiten, wie Sie dieses Verhalten ändern können, aber es ist wahrscheinlich nicht etwas, das Sie auf jedem Computer tun möchten, auf dem Sie Ihre Skripte herumtragen – insbesondere, wenn einige dieser Computer nicht Ihre eigenen sind.
  2. PowerShell erlaubt standardmäßig keine externe Skriptausführung.
    Die ExecutionPolicy-Einstellung 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 unter So erlauben Sie die Ausführung von PowerShell-Skripten unter Windows 7 ändern können. Dies möchten Sie jedoch auch nicht auf jedem Computer tun.
  3. Einige PowerShell-Skripts funktionieren ohne Administratorrechte nicht.
    Selbst wenn Sie mit einem Konto auf Administratorebene arbeiten, müssen Sie die Benutzerkontensteuerung (User Account Control, UAC) durchlaufen, um bestimmte Aktionen auszuführen. Wir wollen dies nicht deaktivieren, aber es ist trotzdem schön, wenn wir es ein bisschen 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 Skripte etwas 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 – den .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 Batch-Datei, um das PowerShell-Skript über die Befehlszeile für uns aufzurufen.

Daher müssen wir 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 sich die Batchdatei im selben Ordner wie Ihr PowerShell-Skript befinden und denselben Dateinamen haben. Wenn Ihr PowerShell-Skript also «MyScript.ps1» heißt, sollten Sie Ihre 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 -Command "& '%~dpn0.ps1'"
PAUSE

Wenn die anderen Sicherheitsbeschränkungen nicht vorhanden wären, wäre dies wirklich alles, was zum Ausführen eines PowerShell-Skripts aus einer Batchdatei erforderlich ist. Tatsächlich sind die erste und die 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 AUS schaltet das Befehlsecho aus. Dies verhindert nur, dass Ihre anderen Befehle auf dem Bildschirm angezeigt werden, wenn die Batchdatei ausgeführt wird. Diese Zeile wird durch das Symbol at (@) davor ausgeblendet.

PowerShell.exe -Befehl «& ‘% ~ dpn0.ps1′» führt tatsächlich das PowerShell-Skript aus. PowerShell.exe kann natürlich von jedem CMD-Fenster oder jeder Batch-Datei aufgerufen werden, um PowerShell wie gewohnt auf einer nackten Konsole zu starten. Sie können damit auch Befehle direkt aus einer Batchdatei ausführen, indem Sie den Parameter -Command und die entsprechenden Argumente angeben. Die Art und Weise, wie dies für unsere .PS1-Datei verwendet wird, erfolgt mit der speziellen Variablen% ~ dpn0. % ~ Dpn0 wird aus einer Batchdatei ausgeführt und ergibt den Laufwerksbuchstaben, den Ordnerpfad und den Dateinamen (ohne Erweiterung) der Batchdatei. 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 Stapelausführung und wartet auf Benutzereingaben. Dies ist im Allgemeinen nützlich, um am Ende Ihrer Batch-Dateien zu stehen, damit Sie die Befehlsausgabe überprüfen können, bevor das Fenster verschwindet. Wenn wir jeden Schritt testen, wird die Nützlichkeit dieses Schritts offensichtlicher.

So wird die grundlegende Batch-Datei 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.

Natürlich wurde das PowerShell-Skript nicht ausgeführt, aber das ist zu erwarten – wir haben schließlich nur das erste unserer vier Probleme behoben. Hier werden jedoch einige wichtige Punkte demonstriert:

  1. Der Fenstertitel zeigt, dass das Batch-Skript PowerShell erfolgreich gestartet hat.
  2. Die erste Ausgabezeile zeigt, dass ein benutzerdefiniertes PowerShell-Profil verwendet wird. Dies ist das potenzielle Problem Nr. 4, das oben aufgeführt ist.
  3. Die Fehlermeldung zeigt die geltenden ExecutionPolicy-Einschränkungen an. Das ist unser Problem Nr. 2.
  4. Der unterstrichene Teil der Fehlermeldung (der nativ von der PowerShell-Fehlerausgabe ausgeführt wird) zeigt, dass das Batch-Skript korrekt auf das beabsichtigte PowerShell-Skript ausgerichtet war (D: Script Lab MyScript.ps1). 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 eine Ausgabe 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 'Custom PowerShell profile in effect!'

Die ExecutionPolicy auf dem Testsystem ist hier auf RemoteSigned eingestellt. Dies ermöglicht die Ausführung lokal erstellter Skripte (wie das Profilskript), während Skripte von externen Quellen blockiert werden, sofern sie nicht von einer vertrauenswürdigen Stelle 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 LabMyScript.ps1' -Value "[ZoneTransfer]`nZoneId=3" -Stream 'Zone.Identifier'

Dadurch wird der alternative Datenstrom Zone.Identifier in MyScript.ps1 so festgelegt, dass 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 -Path 'D:Script LabMyScript.ps1' -Stream 'Zone.Identifier'

Schritt 2: Umgehen von ExecutionPolicy.

Das Umgehen der ExecutionPolicy-Einstellung über CMD oder ein Batch-Skript ist eigentlich ziemlich einfach. Wir ändern nur die zweite Zeile des Skripts, um dem Befehl PowerShell.exe einen weiteren Parameter hinzuzufügen.

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

Mit dem Parameter -ExecutionPolicy können Sie die ExecutionPolicy ändern, die beim Erstellen einer neuen PowerShell-Sitzung verwendet wird. Dies bleibt nicht über diese Sitzung hinaus bestehen, sodass wir PowerShell jederzeit wie folgt ausführen können, ohne die allgemeine Sicherheitslage des Systems zu beeinträchtigen. Nachdem wir das behoben haben, versuchen wir es noch einmal:

Nachdem 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 eingeschränkter Benutzer ausführen. Das Skript wird tatsächlich von einem Konto mit Administratorrechten ausgeführt, aber die Benutzerkontensteuerung ist im Weg. Obwohl Details darüber, wie das Skript den Administratorzugriff überprüft, den Rahmen dieses Artikels sprengen, wird der folgende Code zur Demonstration verwendet:

if (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{Write-Output 'Running as Administrator!'}
else
{Write-Output 'Running Limited!'}
Pause

Sie werden auch feststellen, dass die Skriptausgabe jetzt zwei «Pause» -Operationen enthält – eine aus dem PowerShell-Skript und eine aus der Batch-Datei. Der Grund dafür wird im nächsten Schritt deutlicher.

Schritt 3: Administratorzugriff erhalten.

Wenn in Ihrem Skript keine Befehle ausgeführt werden, für die eine Erhöhung erforderlich ist, und Sie sich ziemlich sicher sind, dass Sie sich keine Sorgen darüber machen müssen, dass benutzerdefinierte Profile von anderen im Weg stehen, können Sie den Rest überspringen. Wenn Sie jedoch einige Cmdlets auf Administratorebene ausführen, benötigen Sie dieses Teil.

Leider gibt es keine Möglichkeit, die Benutzerkontensteuerung für die Erhöhung innerhalb einer Batchdatei oder einer CMD-Sitzung auszulösen. Mit PowerShell können wir dies jedoch mit Start-Process tun. Bei Verwendung von «-Verb RunAs» in den Argumenten versucht Start-Process, eine Anwendung mit Administratorrechten zu starten. Wenn die PowerShell-Sitzung noch nicht erhöht ist, wird eine UAC-Eingabeaufforderung ausgelöst. Um dies aus der Batch-Datei zum Starten unseres Skripts zu verwenden, werden am Ende zwei PowerShell-Prozesse erzeugt – einer zum Starten von Start-Process und einer von Start-Process, 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 -File ""%~dpn0.ps1""' -Verb RunAs}"

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

Nach dem Klicken durch die UAC-Eingabeaufforderung wird eine neue PowerShell-Instanz erzeugt. Da dies natürlich eine neue Instanz ist, wird der Hinweis zum Profilskript erneut angezeigt. Dann wird MyScript.ps1 ausgeführt und wir sehen, dass wir uns tatsächlich in einer erhöhten Sitzung befinden.

Und es gibt den Grund, warum wir auch hier zwei Pausen haben. Ohne die im PowerShell-Skript würde die Ausgabe des Skripts nie angezeigt. Das PowerShell-Fenster wird einfach angezeigt und ausgeblendet, sobald das Skript ausgeführt wird. Und ohne die Pause in der Batch-Datei könnten wir nicht sehen, ob beim Starten von PowerShell überhaupt Fehler aufgetreten sind.

Schritt 4: Umgehen mit benutzerdefinierten PowerShell-Profilen.

Lassen Sie uns jetzt diesen fiesen Hinweis auf benutzerdefinierte Profile loswerden, sollen wir? Hier ist es kaum ein Ärgernis, aber wenn das PowerShell-Profil eines Benutzers die Standardeinstellungen, Variablen oder Funktionen auf eine Weise ändert, die Sie mit Ihrem Skript möglicherweise nicht erwartet haben, können sie sehr problematisch sein. Es ist viel einfacher, Ihr Skript vollständig ohne das Profil auszuführen, sodass Sie sich darüber keine Sorgen machen müssen. Dazu müssen wir nur noch einmal die zweite Zeile der Batch-Datei ändern:

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

Das Hinzufügen des Parameters -NoProfile zu beiden Instanzen von PowerShell, die vom Skript gestartet werden, bedeutet, dass das Profilskript des Benutzers in beiden Schritten vollständig umgangen wird und unser PowerShell-Skript in einer ziemlich vorhersehbaren Standardumgebung ausgeführt wird. Hier sehen Sie, dass in keiner der gespawnten Shells ein benutzerdefinierter Profilhinweis vorhanden ist.

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

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

Die Ausgabe sieht dann folgendermaßen aus:

(Natürlich können Sie bei Skripten, die keine Administratoren sind, auch an dieser Stelle auf eine Pause am Ende des Skripts in Ihrem PowerShell-Skript verzichten, da alles im selben Konsolenfenster erfasst wird und dort durch die Pause am Ende von angehalten wird die Batch-Datei trotzdem.)

Abgeschlossene Batchdateien.

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

Ohne Administratorzugriff:

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

Mit Administratorzugriff:

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

Denken Sie daran, die Batchdatei in demselben Ordner wie das PowerShell-Skript abzulegen, für das Sie sie verwenden möchten, und geben Sie ihr denselben 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, dies erspart Ihnen jedoch diese Probleme und Sie müssen sich später keine Gedanken mehr über das Zurücksetzen der Änderungen machen.

Verweise:

Continue Reading
Click to comment

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Tendencia