Windows PowerShell: die erweiterte Funktion Lifecycle

Die erweiterten Funktionen der Windows PowerShell – Skript Cmdlets genannt — kann etwas verwirrend sein, aber hier ist eine Möglichkeit, ihre Funktionen Testsetup- und leiten.

Don Jones

Es wurde ein fortlaufender Punkt Verwirrung für eine Reihe von Studenten in einigen meiner vor-Ort-Windows PowerShell-Klassen. Ich hoffe, dass es hier genauer erforschen hilft auch einige Verwirrung für Sie entladen. Das Thema ist die erweiterten Funktionen von Windows PowerShell, informell als Skript Cmdlets bezeichnet. Die Vorlage für diese Art von Funktion sieht folgendermaßen aus:

Function Do-Something { [CmdletBinding()] param( [Parameter(Mandatory=$True, ValueFromPipeline=$True)] [string[]]$computername ) BEGIN {} PROCESS {} END {} }

Es gibt einige Aspekte, die zu diesen Cmdlets verwirrend. In diesem Feld ein, z. B. einen definierten Eingabeparameter - Computername bezeichnet ist. Dies kann Benutzereingaben aus der Pipeline. Das bedeutet, dass Sie diese Funktion auf zwei unterschiedliche Arten aufrufen können. Erstens können Sie Zeichenfolgen hinein, geleitet haben, z. B. aus einer Textdatei, ein Computername pro Zeile enthält:

Get-Content names.txt | Do-Something

Können Sie auch einfach eine oder mehrere Computernamen direkt an den Parameter übergeben, ohne Verwendung der Pipeline auf allen:

Do-Something –computername SERVER1,SERVER2

Im ersten Beispiel wird die Funktion BEGIN-Block zuerst ausgeführt. Der PROCESS-Block führt anschließend einmal für jeden Computernamen geleitet-in. Die Variable $Computername enthält nur einen Computernamen zu einem Zeitpunkt. Schließlich, nachdem sie alle verarbeitet, führt der END-Block einmal aus.

Im zweiten Beispiel führen Sie niemals die BEGIN und END-Blöcke. Der PROCESS-Block wird nur einmal ausgeführt, und $Computername enthält alle Namen, die an den Parameter übergeben wurde.

Dieser extreme Unterschied im Verhalten machen es schwierig, einrichten und Cleanuptasks, die in beiden Situationen ausgeführt. Es kann auch über den Umgang mit Parametern Computername $ Verwirrung. Im ersten Beispiel enthält es nur einen Wert in einer Zeit, während im zweiten enthalten einen oder mehrere Werte, je nachdem, was an den Parameter "– Computername" angegeben wurde. Sie können das $Computername-Problem beheben, indem man einfach eine ForEach-Schleife innerhalb der PROCESS-Block:

Function Do-Something { [CmdletBinding()] param( [Parameter(Mandatory=$True, ValueFromPipeline=$True)] [string[]]$computername ) BEGIN {} PROCESS { Foreach ($computer in $computername) { # use $computer here } } END {} }

Diese Technik garantiert, dass die Variable $Computer nur einen Computernamen zu einem Zeitpunkt enthalten, so ist es besser, statt $Computername mit zu arbeiten.

Die Einrichtung und die Bereinigung ist etwas komplizierter. Sie möchten das Setup direkt in der PROCESS-Block führen. Dieser Block kann mehrmals ausgeführt werden, wenn Objekte an die Pipeline gesendet werden. Sie können nicht auf der anderen Seite Setup direkt in der BEGIN-Block abgelegt. Die nicht ausgeführt, wenn nichts im geleitet wird. Es gibt natürlich viele Möglichkeiten, wie, die Sie dieses beschäftigen konnte, aber das scheint das beste sein:

Function Do-Something { [CmdletBinding()] param( [Parameter(Mandatory=$True, ValueFromPipeline=$True)] [string[]]$computername ) BEGIN { $setup_done = $false function DoSomethingSetup { set-variable -name setup_done -value $true -scope 1 } DoSomethingSetup } PROCESS { if (-not $setup_done) { DoSomethingSetup } Foreach ($computer in $computername) { # use $computer here } } }

Dies nutzt die Tatsache, dass die BEGIN, PROCESS und END-Blöcke, die alle einen gemeinsamen Bereich, was bedeutet, dass sie die gleichen Variablen Teilen zu teilen. Durch die Einrichtung einer Variablen als ein Kennzeichen können Sie sicher sein von der BEGIN-Block den Schlüsselinhalt – meine DoSomethingSetup-Funktion – nur einmal aufgerufen.

Beachten Sie, dass die "DoSomethingSetup"-Funktion verwenden, um eine spezielle Technik zum Setzen des Kennzeichens muss $ True einmal, Sie haben die Installationsaufgaben abgeschlossen. Da es sich um eine Funktion handelt, hat DoSomethingSetup einen eigenen Bereich. Normalerweise können sie den Wert einer Variablen von außerhalb dieses Bereichs nicht ändern. Sie können die erforderliche Variable mithilfe des Cmdlets Set-Variable explizit ändern.

Den gleichen Trick für die Cleanuptasks ausführen ist etwas schwieriger. Im ersten Beispiel, in dem Objekte in Something geleitet werden, wird der END-Block ausgeführt. Sie könnten Ihre Cleanuptasks nur dort ablegen. Im zweiten Beispiel, in dem nichts an die Pipeline gesendet wird, wird Ende jedoch niemals ausgeführt. Der PROCESS-Block wird nur einmal ausgeführt, so dass es wird nicht notwendigerweise "wissen", dass der END-Block nicht ausgeführt.

Sie haben können nicht nur den PROCESS-Block innerhalb der END-Block-Funktion aufrufen. Wenn Objekte an die Pipeline gesendet werden, wird der PROCESS-Block mehrmals ausführen – und nicht den END-Block mehrmals aufrufen möchten.

Es gibt einige hinterhältigen Möglichkeiten, um das Problem zu lösen, aber die einfachere Lösung ist oft die beste: Wenn Sie eine Art von Cleanup-Aktivität (z. B. das Schließen einer Datenbankverbindung) benötigen, verwenden die BEGIN und END-Blöcke ganz vergessen. Haben Sie davon ausgehen, dass es nur einmal ausgeführt, und setzen Sie einfach Ihr Setup und Cleanup genau dort geht den PROCESS-Block.

Kann es ein wenig verschwenderisch – möglicherweise öffnen und Schließen einer Datenbankverbindung wiederholt, z. B. – aber es ist wirksam. Außerdem entfällt für haben seltsame und schwer verständlichen Perambulations innerhalb des Codes.

Diese Programmierfunktionen, Pipeline und nicht-Pipeline-Szenarien zu behandeln, kann schwierig sein. In einigen kommenden Spalten werde ich einige der Möglichkeiten Teilen andere Leute dieses Problem gelöst haben, so Sie verschiedene Optionen in Ihrer eigenen Umgebung müssen.

Denny Cherry

Don Jones ist ein Microsoft MVP Award Empfänger und Autor von "Erfahren Sie Windows PowerShell in ein Monat von Rezepten" (Manning Publications Co., 2010), ein Buch soll jeder Administrator Windows PowerShell wirksam zu helfen. Jones bietet auch Schulungen für Öffentliche und vor-Ort-Windows PowerShell. Sie erreichen ihn über seine Website unter ConcentratedTech.com.

Verwandter Inhalt