BillionPhotos.com - stock.adobe.

Rückgabewerte in PowerShell-Funktionen sparen Code-Arbeit

In bestimmten Fällen können Sie das Schlüsselwort return nutzen, um den Geltungsbereich einer Funktion zu erweitern und den Umfang des gesamten PowerShell-Skriptes zu reduzieren.

Wenn Sie Get-Funktionen schreiben möchten, die Werte an die Konsole zurückgeben, gibt es dafür verschiedene Wege, die unterschiedlich effizient sind.

Arbeiten Sie mit PowerShell-Funktionen, kommen Sie relativ weit, wenn Sie nur Funktionen schreiben, die keine Daten zurückgeben. Zum Beispiel liefern viele Set- oder Update-Funktionen ohne den Parameter -Verbose kein Feedback an die Konsole. Ein return-Schlüsselwort kann veranlassen, dass ein Wert zurückzugeben wird oder einen Exit-Punkt in einem Bereich bereitgestellt wird. Sie müssen dafür aber genau verstehen, wie Rückgabewerte in PowerShell funktionieren.

Methode 1: Ausgabe eines Wertes

Am einfachsten ist es, wenn Sie PowerShell den gewünschten Wert ausgeben lassen. Im folgenden Beispiel suchen wir nach dem Datei-Explorer-Prozess. Statt den gesamten Where-Object-Ausdruck einzugeben, können Sie ihn mit einer Funktion kürzen:

Function Get-Explorer {
    Get-Process | Where-Object Name -eq 'Explorer'
}

Sie werden in der obenstehenden Funktion vielleicht nicht direkt erkennen, wie dieser Code etwas zurückgibt. Das Cmdlet Get-Process, das normalerweise die auf dem Computer ausgeführten Prozesse zurückgibt, weist jedoch darauf hin. Da die Rückgabe dieses Cmdlets nicht auf eine Variable festgelegt ist, wird es direkt an die Pipeline ausgegeben. Um es expliziter zu machen, weisen Sie es einer Variablen zu und geben Sie diese aus:

Function Get-Explorer {
    $explorer = Get-Process | Where-Object Name -eq 'Explorer'
    $explorer
}

Sie können dies mit dem Cmdlet Write-Output weiter verfeinern:

Function Get-Explorer {
    $explorer = Get-Process | Where-Object Name -eq 'Explorer'
    Write-Output $explorer
}

Das obenstehende Beispiel ist zwar leicht zu verstehen, doch im alltäglichen Einsatz leidet die Effizienz, wenn Sie den ausgegebenen Wert in einer Variablen speichern. Während das dritte Beispiel besser lesbar ist, ist die erste die empfohlene Form.

Alle Beispiele erzeugen eine Ausgabe im Tabellenformat (Abbildung 1).

Abbildung 1: Alle drei Funktionen geben dieselbe Tabelle aus.
Abbildung 1: Alle drei Funktionen geben dieselbe Tabelle aus.

Wenn Sie Get-Process bereits verwendet haben, sollte diese Ausgabe vertraut aussehen, da es sich um ein Prozessobjekt handelt, das Sie mit der GetType ()-Methode überprüfen können (Abbildung 2).

Abbildung 2: Die GetType()-Methode zeigt den Datentyp der Variablen.
Abbildung 2: Die GetType()-Methode zeigt den Datentyp der Variablen.

Mit diesem Code haben Sie also alles, was Sie brauchen, um Output in einer PowerShell-Funktion zurückzugeben. Aber es gibt eine andere Methode mit ihren eigenen Vorteilen.

Methode 2: Verwenden des Schlüsselworts return

Wenn Sie bereits Erfahrung mit anderen Programmiersprachen haben, zum Beispiel C, kennen Sie das Schlüsselwort return wahrscheinlich schon. Der Unterschied zwischen einer Rückgabe in C und in PowerShell besteht darin, dass C nur Werte zurückgibt, wenn Sie das mit return veranlassen, PowerShell jedoch Werte ohne das Schlüsselwort an die Pipeline zurückgeben kann.

Da wir wie in der ersten Methode Werte von einer PowerShell-Funktion zurückgeben können, ist der Wert des Schlüsselworts return möglicherweise nicht sofort ersichtlich. Der Unterschied zwischen der Rückgabe von Werten mit Write-Output und mit return besteht darin, dass zweiteres den aktuellen Geltungsbereich verlässt. Wenn Sie sich innerhalb einer Funktion befinden und einen Wert mit return zurückgeben, gibt die Funktion diesen Wert zurück und beendet den Vorgang.

Um dies zu demonstrieren, verwenden wir im folgenden Beispiel das Schlüsselwort return zweimal, um alle PowerShell-Prozesse zurückzugeben, die auf einem Computer ausgeführt werden, sowohl aus Windows PowerShell als auch aus Open Source PowerShell:

Function Get-PowerShellProcess {
    return Get-Process | Where-Object Name -eq 'powershell'
    return Get-Process | Where-Object Name -eq 'pwsh'
}

Hätten wir diese Befehle mit Write-Output geschrieben, würden sowohl die Powershell- als auch die Pwsh-Prozesse ausgegeben. Da wir jedoch das return verwenden, werden die Windows-PowerShell-Prozesse zurückgegeben und anschließend beendet. Hier ist die Ausgabe auf dem Computer:

Abbildung 3: Das Schlüsselwort return beendet die Funktion, nachdem sie den ersten Prozess ausgegeben hat.
Abbildung 3: Das Schlüsselwort return beendet die Funktion, nachdem sie den ersten Prozess ausgegeben hat.

Um sowohl Powershell- als auch Pwsh-Prozesse zurückzugeben, ersetzen Sie return durch Write-Output oder entfernen Sie es vollständig:

Function Get-PowerShellProcess {
    Get-Process | Where-Object Name -eq 'powershell'
    Get-Process | Where-Object Name -eq 'pwsh'
}

PowerShell generiert dann eine Ausgabe für beide Prozesse (Abbildung 4).

Abbildung 4: Eine Funktion ohne das return-Schlüsselwort führt die gesamte Funktion durch und gibt Informationen für beide Prozesse aus.
Abbildung 4: Eine Funktion ohne das return-Schlüsselwort führt die gesamte Funktion durch und gibt Informationen für beide Prozesse aus.

Vermeiden Sie die Verwendung von return, um beide Arten von Prozessen zurückzugeben.

Wofür benötigen Sie return?

Es gibt Fälle, in denen return nützlicher ist als Write-Output. Nehmen wir zum Beispiel an, Sie möchten eine Funktion schreiben, die den ersten Index eines Zeichens in einer Zeichenfolge zurückgibt, und wenn er nicht vorhanden ist, soll sie -1 zurückgeben. Wenn Sie Write-Output verwenden möchten, so dass die Funktion effizient beendet wird, wenn sie das Zeichen gefunden hat, sieht das folgendermaßen aus:

Function Find-Character {
    param ([char]$Char,[string]$String)
    $found = $false
    for($x=0;$x -lt $String.Length;$x++) {
        If($String[$x] -eq $Char) {
            Write-Output $x
            $found = $true
            break
        }
    }
    if (-not $found) {
        Write-Output -1
    }
}

Das Skript bricht aus der for-Schleife aus, wenn es das Zeichen findet, wiederholt diese Überprüfung jedoch auch weiter im Skript. Dies ist für eine einfache Operation zu komplex. Es ist effizienter, return mit dem folgenden Code zu verwenden:

Function Find-Character {
    param ([char]$Char,[string]$String)
    for($x=0;$x -lt $String.Length;$x++) {
        If($String[$x] -eq $Char) {
            return $x
        }
    }
    return -1
}

Dieses Skript ist kürzer und leichter zu lesen und erzielt das gleiche Ergebnis. Wenn die erste Rückgabe zum ersten Mal ausgeführt wird, gibt sie sofort $ x zurück und beendet die Funktion. Wenn das Zeichen nicht gefunden wird, fährt der Code mit der letzten Rückgabe fort und gibt -1 zurück.

Erfahren Sie mehr über Serverbetriebssysteme