Sobald Sie sich daran gewöhnt haben, PowerShell-Skripte zu schreiben, müssen Sie sich mit der Modularisierung des Codes vertraut machen. Modularisierung ist nur ein schicker Begriff für die Erstellung von Code in Bausteinen. In der PowerShell-Welt sind PowerShell-Funktionen eine der besten Möglichkeiten, dies zu tun.
Wenn Sie ein PowerShell-Skript schreiben, haben Sie viele Optionen, wie Sie den Code schreiben. Sie könnten tausend Zeilen Code schreiben, die Hunderte von Aufgaben erledigen, alles in einem einzigen, ununterbrochenen Codeblock. Das wäre eine Katastrophe. Stattdessen sollten Sie Funktionen schreiben.
Funktionen erhöhen die Benutzerfreundlichkeit und Lesbarkeit Ihres Codes erheblich und erleichtern die Arbeit damit. In diesem Tutorial lernen Sie, Funktionen zu schreiben, Funktionenparameter hinzuzufügen und zu verwalten und Funktionen so einzurichten, dass sie Pipeline-Eingaben akzeptieren. Aber zuerst werfen wir einen Blick auf ein paar Begriffe.
Dieser Beitrag wurde aus meinem Buch PowerShell für Sysadmins: Workflow-Automatisierung leicht gemacht entnommen. Wenn Sie in diesem Tutorial etwas lernen, sollten Sie unbedingt das Buch lesen, um mehr über Funktionen und viele weitere PowerShell-Leckereien zu erfahren.
Funktionen vs. Cmdlets
Das Konzept einer Funktion könnte Ihnen vertraut vorkommen, weil es ein wenig wie die Cmdlets klingt, die Sie wahrscheinlich bereits verwendet haben. Befehle wie Start-Service
und Write-Host
sind zum Beispiel ähnlich wie Funktionen. Dies sind benannte Code-Stücke, die ein einzelnes Problem lösen. Der Unterschied zwischen einer Funktion und einem Cmdlet besteht darin, wie diese Konstrukte erstellt werden.
A cmdlet isn’t written with PowerShell. It’s written in another language, typically something like C#. The cmdlet is then compiled and made available inside PowerShell.
Auf der anderen Seite werden Funktionen in PowerShell geschrieben, nicht in einer anderen Sprache.
Sie können sehen, welche Befehle Cmdlets sind und welche Funktionen sind, indem Sie das Cmdlet Get-Command
und seinen Parameter CommandType
wie unten gezeigt verwenden
Dieser Befehl gibt alle Funktionen zurück, die derzeit in Ihrer PowerShell-Sitzung geladen sind oder in Modulen, die für PowerShell verfügbar sind.
Verwandt: Verständnis und Erstellung von PowerShell-Modulen
Voraussetzungen
Wenn Sie alle Beispiele mitverfolgen möchten, stellen Sie bitte sicher, dass Sie eine Version von PowerShell zur Verfügung haben. Es gibt keine spezifischen Versionsanforderungen für dieses Tutorial. Stellen Sie außerdem sicher, dass Sie einen geeigneten Code-Editor wie Visual Studio Code haben, um Code-Snippets zu kopieren, einzufügen und auszuführen.
Erstellen einer einfachen Funktion
Bevor Sie eine Funktion verwenden können, müssen Sie sie definieren. Um eine Funktion zu definieren, verwenden Sie das Schlüsselwort „function“, gefolgt von einem beschreibenden, benutzerdefinierten Namen und einer Reihe geschweifter Klammern. Innerhalb der geschweiften Klammern befindet sich ein Skriptblock, das von PowerShell ausgeführt werden soll.
Unten sehen Sie eine grundlegende Funktion und die Ausführung dieser Funktion. Diese Funktion namens Install-Software
verwendet Write-Host
, um eine Nachricht in der Konsole anzuzeigen. Sobald sie definiert ist, können Sie den Namen dieser Funktion verwenden, um den Code innerhalb ihres Skriptblocks auszuführen.
Namensgebung mit Verb-Nomen
A function’s name is important. You can name your functions whatever you want, but the name should always describe what the function does. The function-naming convention in PowerShell is the Verb-Noun syntax.
Der Name einer Funktion sollte immer mit einem Verb gefolgt von einem Bindestrich und einem Nomen beginnen. Verwenden Sie das Cmdlet Get-Verb
, um die Liste der „zugelassenen“ Verben zu finden.
Ändern des Funktionsverhaltens
Wenn Sie das Verhalten einer Funktion ändern möchten, können Sie einfach den Code ändern, den die Funktion ausführt, wie unten gezeigt.
Jetzt, da Sie den Code innerhalb der Funktion geändert haben, wird eine etwas andere Nachricht angezeigt.
Definition einer erweiterten Funktion
Sie können Funktionen an vielen verschiedenen Stellen definieren. In dem obigen Abschnitt geht das Tutorial davon aus, dass Sie den Code einfach direkt in die PowerShell-Konsole kopiert und eingefügt haben. Aber das ist nicht die einzige Möglichkeit. Sie können Funktionen auch in einem Skript definieren.
In dem vorherigen Abschnitt haben Sie mit einer kleinen Funktion gearbeitet, daher war es kein großes Problem, sie in der Konsole zu definieren. Meistens werden Sie jedoch viel größere Funktionen haben. Es ist einfacher, diese Funktionen in einem Skript oder einem Modul zu definieren und dann dieses Skript oder Modul aufzurufen, um die Funktion in den Speicher zu laden.
Wie Sie sich vielleicht vorstellen können, könnte es etwas frustrierend sein, eine größere Funktion jedes Mal neu einzutippen, wenn Sie ihre Funktionalität anpassen möchten.
I suggest you now open your favorite editor and store the function in a .ps1 file as you work through the rest of the tutorial.
Hinzufügen von Parametern zu Funktionen
PowerShell-Funktionen können eine beliebige Anzahl von Parametern haben. Wenn Sie Ihre eigenen Funktionen erstellen, haben Sie die Möglichkeit, Parameter einzuschließen und zu entscheiden, wie diese Parameter funktionieren sollen. Die Parameter können obligatorisch oder optional sein und entweder alles akzeptieren oder dazu gezwungen werden, eine begrenzte Liste möglicher Argumente zu akzeptieren.
Verwandt: Alles, was Sie über PowerShell-Parameter wissen wollten
Zum Beispiel könnte die fiktive Software, die Sie über die Funktion Install-Software
installieren, viele Versionen haben. Aber derzeit bietet die Funktion Install-Software
dem Benutzer keine Möglichkeit, anzugeben, welche Version er installieren möchte.
Wenn Sie der einzige Benutzer der Funktion wären, könnten Sie den Code darin jedes Mal ändern, wenn Sie eine bestimmte Version möchten, aber das wäre Zeitverschwendung. Dieser Prozess wäre auch anfällig für potenzielle Fehler, ganz zu schweigen davon, dass Sie möchten, dass andere Ihren Code verwenden können.
Die Einführung von Parametern in Ihre Funktion ermöglicht es ihr, variabel zu sein. Genau wie Variablen es Ihnen ermöglichten, Skripte zu schreiben, die viele Versionen derselben Situation bewältigen konnten, ermöglichen Ihnen Parameter das Schreiben einer einzigen Funktion, die eine Sache auf viele Arten erledigt.
In diesem Fall möchten Sie, dass sie Versionen derselben Software installiert und dies auf vielen Computern tut.
Lassen Sie uns zunächst einen Parameter zur Funktion hinzufügen, der es Ihnen oder einem Benutzer ermöglicht, die zu installierende Version anzugeben.
Erstellen eines einfachen Parameters
Das Erstellen eines Parameters für eine Funktion erfordert einen param
-Block. Der param
-Block enthält alle Parameter für die Funktion. Definieren Sie einen param
-Block mit dem Schlüsselwort param
, gefolgt von Klammern, wie unten gezeigt.
An diesem Punkt hat sich die tatsächliche Funktionalität Ihrer Funktion nicht geändert. Sie haben lediglich die Rohrleitung installiert, um die Funktion für einen Parameter vorzubereiten.
Zu diesem Zeitpunkt installiert die Funktion tatsächlich keine Software. Sie verwendet nur das Cmdlet
Write-Host
, um die Softwareinstallation zu simulieren, damit Sie sich auf das Schreiben der Funktion konzentrieren können.
Nachdem Sie den param
-Block hinzugefügt haben, können Sie den Parameter erstellen, indem Sie ihn innerhalb der Klammern des param
-Blocks platzieren, wie unten gezeigt.
In dem oben gezeigten param
-Block würden Sie zunächst den Parameterblock definieren. Durch Verwendung des Parameterblocks Parameter()
wird er zu einem „erweiterten Parameter“. Ein leerer Parameterblock wie der hier hat keine Funktion, ist aber erforderlich. Ich werde erklären, wie man ihn im nächsten Abschnitt verwendet.
Lassen Sie uns stattdessen auf den [string]
-Typ vor dem Parametername konzentrieren. Wenn Sie den Parametertyp zwischen eckigen Klammern vor dem Parametervariablennamen platzieren, wandeln Sie den Wert des Parameters in einen bestimmten Typ um. PowerShell versucht immer, jeden Wert, der diesem Parameter übergeben wird, in einen String zu konvertieren – sofern er nicht bereits einer ist. Oben wird alles, was als $Version
übergeben wird, immer als String behandelt.
Das Umwandeln Ihres Parameters in einen Typ ist nicht zwingend erforderlich, aber ich empfehle es dringend. Es definiert explizit den Typ und reduziert Fehler erheblich.
Sie fügen auch $Version
in Ihre Write-Host
-Anweisung ein. Das bedeutet, dass Sie beim Ausführen der Funktion Install-Software
mit dem Parameter Version
und der Übergabe einer Versionsnummer eine entsprechende Anweisung erhalten sollten, wie unten gezeigt.
Lassen Sie uns nun sehen, was Sie mit diesem Parameter tun können.
Das obligatorische Parameterattribut
Sie können den Parameterblock verwenden, um verschiedene Parameterattribute zu steuern, mit denen Sie das Verhalten des Parameters ändern können. Wenn Sie beispielsweise sicherstellen möchten, dass jeder, der die Funktion aufruft, einen bestimmten Parameter übergeben muss, könnten Sie diesen Parameter als obligatorisch definieren.
Standardmäßig sind Parameter optional. Erzwingen wir das Übergeben einer Version, indem wir das Schlüsselwort „Mandatory“ innerhalb des Parameterblocks wie unten gezeigt verwenden.
Wenn Sie die obige Funktion ausführen, sollten Sie die folgende Aufforderung erhalten:

Sobald Sie das Attribut „Obligatorisch“ festgelegt haben, wird die Ausführung der Funktion ohne den Parameter gestoppt, bis der Benutzer einen Wert eingibt. Die Funktion wartet nun, bis der Benutzer einen Wert für den Parameter „Version“ angibt. Sobald dies erfolgt ist, führt PowerShell die Funktion aus.
Um die Abfrage des obligatorischen Parameters zu vermeiden, können Sie einfach einen Wert für den Parameter angeben, wenn Sie die Funktion aufrufen, wie im folgenden Beispiel gezeigt.
Standardparameterwerte
Wenn Sie beispielsweise feststellen, dass Sie immer wieder denselben Wert für einen Parameter übergeben, können Sie einen Standardparameterwert festlegen. Standardparameter sind nützlich, wenn Sie einen bestimmten Wert für einen Parameter erwarten, die meiste Zeit.
Zum Beispiel, wenn Sie 90 Prozent der Zeit Version 2 dieser Software installieren möchten und den Wert nicht jedes Mal festlegen möchten, wenn Sie diese Funktion ausführen, können Sie einen Standardwert von 2 für den Parameter „$Version“ festlegen. Sie können dieses Beispiel unten sehen.
Das Vorhandensein eines Standardparameters hindert Sie nicht daran, einen eigenen Wert zu übergeben. Ihr übergebener Wert überschreibt den Standardwert.
Hinzufügen von Parametervalidierungsattributen
Es ist immer eine gute Idee, die Werte, die Sie über Parameter an eine Funktion übergeben können, einzuschränken. Die beste Möglichkeit, dies zu tun, sind Parametervalidierungsattribute.
Wenn Sie die Informationen begrenzen, die Benutzer (oder auch Sie selbst!) an Ihre Funktionen oder Skripte übergeben können, eliminieren Sie unnötigen Code innerhalb Ihrer Funktion. Angenommen, Sie übergeben den Wert 3 an Ihre Funktion „Install-Software“ und wissen, dass Version 3 eine vorhandene Version ist.
Ihre Funktion geht davon aus, dass jeder Benutzer weiß, welche Versionen existieren, daher berücksichtigt sie nicht, was passiert, wenn Sie Version 4 angeben möchten. In diesem Fall findet die Funktion den entsprechenden Ordner nicht, weil er nicht existiert.
Leben ohne Parametervalidierung
Schauen Sie sich das folgende Beispiel an, wenn Sie den String $Version
in einem Dateipfad verwenden. Wenn jemand einen Wert übergibt, der keinen vorhandenen Ordnernamen vervollständigt (z.B. SoftwareV3 oder SoftwareV4), schlägt der Code fehl.

Sie könnten Fehlerbehandlungscode schreiben, um dieses Problem zu berücksichtigen, oder Sie könnten das Problem von vornherein beheben, indem Sie verlangen, dass der Benutzer nur eine vorhandene Version der Software übergibt. Um die Eingabe des Benutzers einzuschränken, fügen Sie eine Parametervalidierung hinzu.
Hinzufügen der Parametervalidierung
Es gibt verschiedene Arten der Parametervalidierung, aber in Bezug auf Ihre Install-Software
-Funktion funktioniert das [ValidateSet
-Attribut](https://adamtheautomator.com/powershell-validateset/) am besten. Das ValidateSet
-Validierungsattribut ermöglicht es Ihnen, eine Liste der für den Parameter zugelassenen Werte anzugeben. Wenn Sie nur die Zeichenfolge 1
oder 2
berücksichtigen, stellen Sie sicher, dass der Benutzer nur diese Werte angeben kann, sonst schlägt die Funktion sofort fehl und informiert den Benutzer darüber, warum.
Fügen Sie Parametervalidierungsattribute innerhalb des param
-Blocks direkt unter dem ursprünglichen Parameter
-Block wie unten gezeigt hinzu.
Durch das Hinzufügen einer Gruppe von Elementen (1
und 2
) innerhalb der abschließenden Klammern des Attributs ValidateSet
teilen wir PowerShell mit, dass die einzigen gültigen Werte für Version
1
oder 2
sind. Wenn ein Benutzer etwas anderes als das Set übergeben möchte, erhält er eine Fehlermeldung, die ihn darauf hinweist, dass er nur eine bestimmte Anzahl von Optionen hat.

Das Attribut ValidateSet
ist ein häufig verwendetes Validierungsattribut, aber es gibt auch andere. Für eine vollständige Aufschlüsselung aller Möglichkeiten, wie Parameterwerte eingeschränkt werden können, schauen Sie sich die Microsoft-Dokumentation an.
Akzeptieren von Pipeline-Eingaben
Bisher haben Sie eine Funktion erstellt, bei der ein Parameter nur mit der typischen Syntax -ParameterName <Wert> übergeben werden kann. Dies funktioniert, aber Sie haben auch die Möglichkeit, Werte über die PowerShell-Pipeline an Parameter zu übergeben. Lassen Sie uns die Fähigkeit zur Verwendung der Pipeline zu unserer Install-Software-Funktion hinzufügen.
Verwandt: Akzeptieren von Pipeline-Eingaben im ATA PowerShell-Parameterartikel
Fügen Sie zunächst einen weiteren Parameter zu Ihrem Code hinzu, der den Computer angibt, auf dem Sie die Software installieren möchten. Fügen Sie diesen Parameter auch zu Ihrer Write-Host
-Referenz hinzu, um die Installation zu simulieren.
Nachdem Sie den ComputerName
-Parameter zur Funktion hinzugefügt haben, können Sie nun über eine Liste von Computernamen iterieren und die Werte für den Computernamen und die Version an die Install-Software
-Funktion übergeben, wie unten gezeigt.
Anstatt das alles zu tun, sollten Sie lernen, die Pipeline zu verwenden.
Funktion pipeline-kompatibel machen
Leider können Sie mit einer einfachen zuvor erstellten Funktion nicht von der PowerShell-Pipeline profitieren. Sie müssen sich entscheiden, welche Art von Pipeline-Eingabe die Funktion akzeptieren soll und diese implementieren.
A PowerShell function uses two kinds of pipeline input: ByValue
(entire object) and ByPropertyName
(a single object property). Here, because the $computers
array contains only strings, you’ll pass those strings via ByValue
.
Um die Pipeline-Unterstützung hinzuzufügen, fügen Sie dem Parameter, den Sie möchten, ein Parameterattribut hinzu, indem Sie eines von zwei Schlüsselwörtern verwenden: ValueFromPipeline
oder ValueFromPipelineByPropertyName
, wie unten gezeigt.
Sobald Sie die aktualisierte Install-Software
-Funktion geladen haben, rufen Sie sie wie folgt auf:
Führen Sie das Skript erneut aus und Sie sollten etwas Ähnliches erhalten:
Bemerken Sie, dass Install-Software
nur für den letzten String im Array ausgeführt wird. Sie werden sehen, wie Sie dies im nächsten Abschnitt beheben können.
Hinzufügen eines Prozessblocks
Um PowerShell mitzuteilen, diese Funktion für jedes eingehende Objekt auszuführen, müssen Sie einen Prozessblock einfügen. Platzieren Sie den Code, den Sie jedes Mal ausführen möchten, wenn die Funktion Eingabe über die Pipeline empfängt, innerhalb des Prozessblocks. Fügen Sie Ihrem Skript einen Prozessblock wie unten gezeigt hinzu.
Rufen Sie die Funktion jetzt erneut auf, genau wie zuvor. Die Funktion Install-Software
gibt nun drei Zeilen zurück (eine für jedes Objekt).
Der Prozessblock enthält den Hauptcode, den Sie ausführen möchten. Sie können auch begin
– und end
-Blöcke verwenden, um Code auszuführen, der am Anfang und Ende des Funktionsaufrufs ausgeführt wird. Weitere Informationen zu den Blöcken begin
, process
und end
finden Sie in der Microsoft-Dokumentation
Nächste Schritte
Funktionen ermöglichen es Ihnen, Code in diskrete Bausteine aufzuteilen. Sie helfen Ihnen nicht nur, Ihre Arbeit in kleinere, überschaubare Teile zu zerlegen, sondern zwingen Sie auch dazu, lesbaren und testbaren Code zu schreiben.
I now challenge you to look through some old scripts and see where you can add a PowerShell function. Look for patterns in code. Build a function from those patterns. Notice where you’re copying/pasting code snippets and turn those into PowerShell functions!