Wie kann ich eine PowerShell-Hauptfunktion erstellen?

8

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:

%Vor%

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)

    
Bryan Oakley 08.01.2014, 16:18
quelle

4 Antworten

6

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.

Invoke-Command mit einem Skriptblock

Um dies mit invoke-command zu verwenden, wickle einfach das obige Beispiel in einen neuen Skriptblock und benutze das.

%Vor%

Aufruf-Befehl mit einer Datei

Oder speichern Sie es in einer Datei und nennen Sie es so.

Script.ps1

%Vor%

Verwendung:

%Vor%     
Frode F. 08.01.2014, 16:36
quelle
8

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.

    
mjolinor 08.01.2014 16:35
quelle
1

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:

  1. Ein Skript, das eine Aufgabe ausführt
  2. Ein "Bereitstellungs" -Skript, das Skript Nr. 1
  3. umschließt

...

%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%

Ausgabe

Die Ausgabe des obigen Befehls würde wie folgt aussehen:

%Vor%     
Trevor Sullivan 08.01.2014 17:34
quelle
1

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>

Unterfunktionen

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%

Module

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.

Module Hintergrund

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

in die Sitzung %Vor%

(Beachten Sie, dass Sie den Schalter -Force zum erneuten Importieren in derselben Sitzung hinzufügen müssen.)

Module remote ausführen

Wenn Sie es remote ausführen möchten, sollte dies funktionieren:

%Vor%     
Adi Inbar 08.01.2014 16:44
quelle

Tags und Links