Ich habe in der Vergangenheit viele Skriptsprachen verwendet und lerne jetzt PowerShell. In diesen anderen Sprachen definiere ich normalerweise meine Hauptlogik, bevor ich meine Funktionen definiere. Daher wird sich jemand, der den Code liest, zuerst auf die Hauptlogik konzentrieren. Dies geschieht oft in Form einer "Haupt" -Funktion oder -Klasse am Anfang der Datei, die unten aufgerufen wird.
In PowerShell könnte dieses Muster wie folgt aussehen:
%Vor% Das funktioniert gut, aber ich möchte jetzt die Fähigkeit von PowerShell nutzen, Code remote auszuführen. Da $main
ein PowerShell ScriptBlock
-Objekt ist, kann ich [denke ich] diesen Code auf einem entfernten Rechner wie folgt ausführen:
Der Remote-Computer wird jedoch nichts über meine Funktion wissen, da er außerhalb des Bereichs von $main
definiert ist. Ich kann natürlich die Definition der Funktion in $ main verschieben, aber dann muss ich es über die Hauptlogik setzen und ich bin gleich wieder bei meinem ersten Problem.
Gibt es ein gemeinsames Muster zum Schreiben von PowerShell-Skripten, bei denen die Hauptlogik in einer Funktion oder einem Skriptblock am Anfang der Datei liegt, ähnlich wie in vielen traditionellen Sprachen? Wie schreiben Menschen komplexe Skripte - schreiben sie sie immer nur von oben nach unten und streuen Funktionen nach Bedarf oben ein?
Jemand hat dies als mögliches Duplikat der Frage markiert Warum muss ich meine Funktionen zuerst in meinem Powershell-Skript schreiben lassen? . Dies ist kein Duplikat davon. Ich weiß warum Funktionen zuerst definiert werden müssen - ich habe programmiert, seit C die coole neue Sprache war.
Was ich fragen möchte, ist das Muster dafür in Poweshell, insbesondere im Zusammenhang mit dem Wunsch, den Hauptcode remote ausführen zu können.
Gibt es ein allgemeines Muster, um einen main
-Block an die Spitze eines Powershell-Skripts zu setzen? Powershell-Syntax und -Idiome unterscheiden sich ausreichend von traditionellen Sprachen, und selbst viele populäre moderne Skriptsprachen, dass das Muster zum Verschieben der Hauptlogik nach oben nicht offensichtlich ist (oder vielleicht ist es das, aber ich habe einfach nicht die richtigen Beispiele gefunden oder Dokumentation)
Skripte werden von oben nach unten gelesen, so dass Sie vor der Initialisierung keine Referenzen verwenden können. Sie könnten jedoch einen Skript / Skriptblock erstellen, der simuliert, wie Programmiersprachen arbeiten.
In Programmiersprachen wie c # ist% main
eine Funktion. Wenn die App fertig ist, werden die notwendigen Teile geladen (wie Kernfunktionen usw.), und der Event-Handler ruft die Hauptfunktion auf, um die Party zu starten. Mit dem folgenden Ansatz würden Sie das gleiche Verhalten simulieren.
Um dies mit invoke-command
zu verwenden, wickle einfach das obige Beispiel in einen neuen Skriptblock und benutze das.
Oder speichern Sie es in einer Datei und nennen Sie es so.
Script.ps1
%Vor%Verwendung:
%Vor% Wenn Sie die "traditionelle" Struktur in PowerShell emulieren möchten, können Sie dazu die verwenden Begin
, Process
und End
Keywords .
Diese können in beliebiger Reihenfolge im Skript vorkommen, aber der Begin
-Baustein wird immer zuerst ausgeführt, Sie können ihn also am Ende Ihres Skripts platzieren, Ihre Funktionsdefinitionen dort ablegen und Ihre Hauptlogik bei Anfang des Skripts in einem Process
oder End
Block.
Ich persönlich bevorzuge die Weitergabe von ScriptBlock
an einen entfernten Computer mit Invoke-Command
. Nichtsdestoweniger ist es durchaus zulässig, eine vollständige Skriptdatei "von Anfang bis Ende" zu schreiben, die einige lokale Aufgaben ausführt und sie dann auf den lokalen (und / oder entfernten) Computern mithilfe des Parameters -File
für% co_de bereitstellt %.
In diesem Codebeispiel wird eine PowerShell-Skriptdatei dynamisch generiert und anschließend auf den Zielsystemen bereitgestellt. Auf diese Weise müssen Sie nicht mehrere Skriptdateien manuell verwalten:
...
%Vor% Wenn Sie wie ich sind und lieber Invoke-Command
verwenden, müssen die gesamten Inhalte Ihres Skripts in ScriptBlock
enthalten sein, bevor Sie sie mit ScriptBlock
bereitstellen. .
Hier ist ein Beispiel:
%Vor%Die Ausgabe des obigen Befehls würde wie folgt aussehen:
%Vor% AFAIK, es gibt keine Möglichkeit, Unterprogramme nach dem Hauptcode in einer Skriptdatei ( .ps1
) zu definieren, weil der Code sequentiell verarbeitet wird, und wenn Sie eine Funktion aufrufen, bevor sie definiert wird, erhalten Sie einen Fehler / p>
Wenn Sie es so organisieren möchten, dass es klarer ist, welche Teile der Hauptcode und welche Teile Unterroutinen sind, können Sie Funktionen innerhalb einer Funktion deklarieren (die sie auch auf die Funktion beschränkt), aber Sie müssen am Anfang kommen, damit sie definiert sind, bevor sie vom Hauptcode aufgerufen werden:
%Vor%Die einzige Möglichkeit, die Unterprogramme nach der Hauptfunktion anzuzeigen, besteht darin, ein PowerShell-Modul zu verwenden . Wenn Sie das Modul importieren, werden alle von ihm definierten Funktionen importiert, bevor Code ausgeführt wird.
Wenn Sie also die Hauptfunktion ausführen, sind bereits alle Unterprogramme definiert.
Wenn Sie mit Modulen nicht vertraut sind, ist das ganz einfach. Fügen Sie den gesamten Code in eine .psm1
-Datei ein (er muss nicht nur Funktionsdefinitionen enthalten, sondern jeder andere Code wird ausgeführt, wenn das Modul importiert wird). Dann importieren Sie es mit
(Beachten Sie, dass Sie den Schalter -Force
zum erneuten Importieren in derselben Sitzung hinzufügen müssen.)
Wenn Sie es remote ausführen möchten, sollte dies funktionieren:
%Vor%Tags und Links powershell