Magic Quadrant™ für Privileged Access Management 2025: Netwrix zum vierten Jahr in Folge anerkannt. Laden Sie den Bericht herunter.

Plattform
Ressourcen­zentrumBlog
Funktionen in PowerShell-Skripten

Funktionen in PowerShell-Skripten

Feb 12, 2025

PowerShell-Funktionen bündeln wiederverwendbaren Code in modularen, wartbaren Einheiten, die das Scripting vereinfachen und Fehler reduzieren. Definiert mit dem function Schlüsselwort, können sie Parameter enthalten, Pipeline-Eingaben akzeptieren und sich wie Cmdlets verhalten, wenn sie [CmdletBinding()] verwenden. Funktionen unterstützen erweiterte Funktionen wie Fehlerbehandlung mit Try/Catch, ausführliche und Debug-Ausgaben sowie Modulorganisation. Zu den Best Practices gehören aussagekräftige Benennung, modulares Design, das Zurückgeben von Objekten und Dokumentation mit kommentarbasierten Hilfen.

Eine PowerShell-Funktion ist ein Block von Code, der dazu entworfen wurde, eine spezifische Aufgabe zu erfüllen. Sobald eine Funktion erstellt und getestet ist, kann sie in mehreren Skripten verwendet werden, was den Programmieraufwand reduziert und das Risiko von Fehlern verringert. Die Verwendung von gut benannten Funktionen macht Skripte auch leichter lesbar und wartbar. Und da Funktionen Werte zurückgeben können, die als Eingabe für andere Funktionen oder Codeblöcke verwendet werden können, erleichtern sie den Aufbau komplexer Operationen.

Dieser Artikel erklärt alles, was Sie wissen müssen, um mit der Verwendung von PowerShell-Funktionen zu beginnen, einschließlich wichtiger Best Practices und bietet sogar Anleitungen für den Einstieg in fortgeschrittenere Optionen.

Erste Schritte mit PowerShell Functions

So erstellen Sie eine Funktion in PowerShell

Um eine Funktion zu definieren, verwenden Sie das Schlüsselwort function. Die grundlegende Syntax lautet wie folgt:

      function <Function-Name> { 

    <Code-Block> 
}
      

Der Code innerhalb der geschweiften Klammern {} wird ausgeführt, wenn die Funktion aufgerufen wird.

Wenn Sie möchten, können Sie das Schlüsselwort param verwenden, um Funktionsparameter zusammen mit Datentypen, Standardwerten und so weiter zu spezifizieren. Hier ist die Syntax mit hinzugefügten Parametern: 

      function <Function-Name> { 

    [param( 

        [<ParameterType>]$<ParameterName>, 

        [<ParameterType>]$<ParameterName2> = <DefaultValue> 

    )] 

    <Code-Block> 

}
      

Dieses PowerShell-Funktionsbeispiel wird zwei Zahlen multiplizieren und das Ergebnis anzeigen:

      function Multiply-Numbers { 

    param ( 

        [int]$Number1, 

        [int]$Number2 

    ) 

    $Result = $Number1 * $Number2 

    Write-Output "The multiplication value of $Number1 and $Number2 is $Result." 

}
      
Image

Eine Funktion speichern

Um eine Funktion zu speichern, speichern Sie sie einfach in einer Skriptdatei mit einer.ps1-Erweiterung.

Aufruf einer Funktion

Um eine Funktion in PowerShell aufzurufen, geben Sie den Namen der Funktion gefolgt von allen notwendigen benannten Parametern ein. Zum Beispiel, so rufen Sie die Funktion auf, die wir oben definiert haben:

      Multiply-Numbers -number1 6 -Number2 8 

      
Image

Ausführen einer Funktion als Teil der aktuellen Sitzung (Dot-Sourcing)

Dot-Sourcing ermöglicht es Ihnen, ein PowerShell-Skript so auszuführen, als wäre es direkt in Ihrer aktuellen Konsolensitzung definiert. Um Dot-Sourcing zu verwenden, stellen Sie dem Funktionsnamen beim Aufrufen einen Punkt und ein Leerzeichen (. ) voran.

Nehmen wir zum Beispiel an, wir hätten die folgende Funktion definiert, die Add-Numbers: 

      function Add-Numbers { 

    param ( 

        [int]$Number1, 

        [int]$Number2 

    ) 

    $Sum = $Number1 + $Number2 

    Write-Output "The sum of $Number1 and $Number2 is $Sum." 

}
      

Wir können diese Funktion in unsere Sitzung einbinden, wie hier gezeigt:

Image

Benennen Ihrer PowerShell-Funktionen

Um den größten Nutzen aus PowerShell-Funktionen zu ziehen, stellen Sie sicher, dass Sie diese Richtlinien beim Benennen Ihrer Funktionen befolgen.

Verwenden Sie das Verb-Substantiv-Format.

PowerShell bietet eine Reihe von vordefinierten Cmdlets, deren Namen einem spezifischen Format folgen: einem Verb, das die auszuführende Aktion angibt, gefolgt von einem Substantiv, das das zu bearbeitende Objekt benennt. Zum Beispiel ruft das Cmdlet get-user Informationen über einen Benutzer ab und remove-item löscht ein bestimmtes Element.

Es ist eine bewährte Methode, für die von Ihnen erstellten Funktionen dieselbe Benennungskonvention zu verwenden. Dadurch können Sie Ihre Funktionen effektiver gestalten und sie leichter wiederverwenden.

Verwenden Sie genehmigte Verben.

PowerShell bietet eine Liste empfohlener Verben für die Verwendung in Funktionen. Um die Liste einzusehen, führen Sie einfach das folgende Cmdlet aus:

      Get-Verb 

      

Wählen Sie aussagekräftige Substantive.

Es ist entscheidend, einer Funktion nicht denselben Namen wie einem integrierten Cmdlet zu geben. Eine gute Methode, um dieses Problem zu vermeiden, ist die Verwendung von allgemeinen Substantiven wie user und data. zu vermeiden. Wählen Sie stattdessen Substantive, die deutlich die Art der Daten anzeigen, auf die die Funktion wirkt. Zum Beispiel ist es leicht zu verstehen, wie sich diese Funktionen unterscheiden: Get-EmployeeData, Get-UserInfo und Get-ServiceInfo.

Vermeiden Sie die Verwendung von Funktionsnamen zu Versionszwecken.

Das Anhängen von Versionsnummern an Funktionsnamen, wie zum Beispiel Get-UserInfoV2, wird nicht empfohlen. Es macht Skripte schwerer verständlich und erhöht das Risiko, alte Versionen einer Funktion zu verwenden. Stattdessen sollte die Versionierung über Ihr Dateiversionierungssystem gehandhabt werden.

Erweiterte Funktionsfähigkeiten

Eingabe von Pipeline-Daten akzeptieren

Sie können eine Funktion so entwerfen, dass sie Eingaben von einer anderen Funktion oder einem Befehl über eine Pipeline akzeptiert, indem Sie das Attribut ValueFromPipeline verwenden. 

Um dies zu veranschaulichen, erstellen wir eine Funktion, die eine Liste von Zeichenketten nacheinander verarbeitet, jede Zeichenkette in Großbuchstaben umwandelt und die Ergebnisse ausgibt. Zur Verdeutlichung werden wir die Verarbeitung der Zeichenketten in drei separate Blöcke unterteilen:

  • BEGIN — Dieser Code wird einmal ausgeführt, bevor irgendwelche Pipeline-Eingaben verarbeitet werden. 
  • PROCESS — Dieser Abschnitt wird für jedes Element ausgeführt, das an die Pipeline übergeben wird, und verarbeitet die Eingabeobjekte einzeln.
  • END — Dieser Code wird ausgeführt, nachdem alle Eingaben verarbeitet wurden, um die Ausgabe abzuschließen.
      function Convert-ToUppercase { 

    [CmdletBinding()] 

    param ( 

        [Parameter(ValueFromPipeline = $true, Mandatory = $true)] 

        [string]$InputString 

    ) 

    BEGIN { 

        Write-Verbose "Starting the uppercase conversion process." 

    } 

    PROCESS { 

        if (-not [string]::IsNullOrWhiteSpace($InputString)) { 

            Write-Verbose "Processing string: $InputString" 

            $InputString.ToUpper() 

        } else { 

            Write-Verbose "Skipped empty or null string." 

        } 

    } 

    END { 

        Write-Verbose "Finished processing all strings." 

    } 

}
      

So könnten wir unsere Funktion aufrufen, um eine Liste von Zeichenketten zu konvertieren, die über eine Pipeline bereitgestellt wird:

      "hello", "world", "this", "is", "powershell" | Convert-ToUppercase -Verbose 

      
Image

Beachten Sie, dass leichte Funktionen, die als filters bezeichnet werden, eine sehr effiziente Möglichkeit bieten, Objekte zu verarbeiten, die durch eine Pipeline geleitet werden. 

Eine Funktion so zu ermöglichen, dass sie sich wie ein Cmdlet verhält

Sie können eine grundlegende Funktion in eine erweiterte Funktion umwandeln, indem Sie das Attribut CmdletBinding verwenden. Dadurch verhält sich die Funktion wie ein Cmdlet, einschließlich der Unterstützung definierter PowerShell-Parameter.

Hier ist die grundlegende Funktion, die wir zuvor definiert haben, um zwei Zahlen zu addieren:

      function Add-Numbers { 

    param ( 

        [int]$Number1, 

        [int]$Number2 

    ) 

    $Sum = $Number1 + $Number2 

    Write-Output "The sum of $Number1 and $Number2 is $Sum." 

}
      

Wir können es wie folgt in eine fortgeschrittene Funktion umwandeln:

      function Add-Numbers { 

    [CmdletBinding()] 

    param ( 

        [Parameter(Mandatory)] 

        [int]$Number1, 

        [Parameter(Mandatory)] 

        [int]$Number2 

    ) 

    process { 

        # Verbose Output 

        Write-Verbose "Starting addition of $Number1 and $Number2" 

        # Debugging Output 

        Write-Debug "Debugging: Ensuring numbers are valid integers" 

        # Perform the Addition 

        try { 

            $Result = $Number1 + $Number2 

            Write-Output $Result 

        } catch { 

            # Handle errors with error stream 

            Write-Error "An error occurred while performing the addition." 

        } 

        # Verbose Completion Message 

        Write-Verbose "Addition completed successfully" 

    } 

}
      

Fordern Sie eine kostenlose Testversion von Netwrix Auditor an

Erstellung von Funktionsmodulen

Ein Funktionsmodul ist eine Datei mit der Endung .psm1, die eine Sammlung von zusammengehörigen Funktionen enthält. Das Organisieren von Funktionen in Modulen erleichtert die Wiederverwendbarkeit und Wartung.

Um ein Funktionsmodul zu erstellen, erstellen Sie einfach eine Textdatei, fügen Sie Ihre Funktionen ein und speichern Sie die Datei mit der Erweiterung .psm1 im Verzeichnis C:\Program Files\WindowsPowerShell\Modules. Zum Beispiel könnten wir ein Modul mit einer arithmetischen Funktion wie der zuvor definierten Funktion Add-Numbers erstellen. 

Um das Modul in Ihre PowerShell-Sitzung zu importieren, verwenden Sie den Befehl Import-Module, wie hier gezeigt: 

Image

Fehlerbehandlung

PowerShell bietet mehrere Fehlerbehandlungstechniken, um Ihnen zu helfen, Probleme reibungslos zu bewältigen, die sonst dazu führen könnten, dass die Ausführung einer Funktion mit einem Fehler stoppt, wie zum Beispiel der Versuch, durch null zu teilen.

Try/Catch/Finally-Blöcke

Wenn Sie wissen, dass eine bestimmte Bedingung ein Problem verursachen könnte, können Sie in Ihrer Funktion Try-, Catch- und Finally-Blöcke verwenden, um diese Bedingung elegant zu behandeln:

  • Versuchen Sie — Dieser Block enthält Code, der einen Fehler verursachen kann (wie eine Divisionsoperation). Wenn kein Fehler auftritt, wird der Catch-Block nicht ausgeführt. 
  • Catch — Wenn ein Fehler im Try-Block auftritt, wird der Catch-Block ihn abfangen und die Fehlerdetails verarbeiten. 
  • Schließlich — Dieser Block ist optional. Wenn er vorhanden ist, wird er nach den Try- und Catch-Blöcken ausgeführt, unabhängig davon, ob ein Fehler aufgetreten ist. 

-ErrorAction-Parameter

Der -ErrorAction-Parameter ermöglicht es Ihnen festzulegen, wie Fehler für eine bestimmte Funktion behandelt werden sollen. Die möglichen Werte sind: 

  • Fortfahren — Eine Fehlermeldung anzeigen und fortfahren.
  • Stopp — Stoppt die Ausführung des Skripts, wenn ein Fehler auftritt. 
  • SilentlyContinue — Unterdrücken Sie die Fehlermeldung und setzen Sie die Ausführung fort. 
  • Anfragen — Fordern Sie den Benutzer auf, wie mit dem Fehler umgegangen werden soll, mit Optionen wie Ja, Nein und Wiederholen.
  • Ignorieren — Ignorieren Sie den Fehler vollständig, ohne auch nur eine Nachricht anzuzeigen.

Unten finden Sie einige Beispiele für den -ErrorAction Parameter: 

      Remove-Item "C:\path\to\nonexistentfile.txt" -ErrorAction SilentlyContinue 

 
Get-Process -Name "Notepad" -ErrorAction Stop
      

$ErrorActionPreference-Variable

Die Variable $ErrorActionPreference steuert, wie Fehler global für alle Cmdlets in einer Sitzung behandelt werden. Diese Variable kann festgelegt werden, um das Verhalten der Fehlerbehandlung für alle Befehle zu beeinflussen, es sei denn, sie wird durch den Parameter -ErrorAction überschrieben.

Detailliertes Beispiel

Im Folgenden finden Sie ein Beispiel, das mehrere Methoden der Fehlerbehandlung verwendet:

  • Die Variable $ErrorActionPreference legt die globale Fehlerbehandlungsvorgabe auf stop, fest, sodass die Ausführung stoppt, wenn ein Fehler auftritt, der nicht anderweitig behandelt wird.
  • Die Try/Catch-Blöcke behandeln den potenziellen Fehler der Division durch Null elegant, ohne die Ausführung zu stoppen. Der Try-Block führt die mathematischen Operationen aus. Wenn er auf eine Division durch Null stößt, wechselt die Verarbeitung zum Catch-Block, der eine Fehlermeldung ausgibt. 
  • Der Finally-Block wird ausgeführt, unabhängig davon, ob ein Fehler aufgetreten ist, und gibt eine Nachricht aus, dass die Operationen abgeschlossen sind. 
      # Set global error action preference to 'Stop' to immediately halt on errors 

$ErrorActionPreference = 'Stop' 

function Perform-MathOperations { 

    param ( 

        [int]$Num1, 

        [int]$Num2 

    ) 

    try { 

        # Performing addition 

        Write-Host "Performing addition: $Num1 + $Num2" 

        $additionResult = $Num1 + $Num2 

        Write-Host "Addition Result: $additionResult" 

        # Checking for division by zero before performing division 

        if ($Num2 -eq 0) { 

            throw "Division by zero is not allowed." 

        } 

        # Performing division 

        Write-Host "Performing division: $Num1 / $Num2" 

        $divisionResult = $Num1 / $Num2 

        Write-Host "Division Result: $divisionResult" 

    } 

    catch { 

        # Catching any error that occurs in the try block 

        Write-Host "An error occurred: $_" 

        Write-Host "Error Type: $($_.Exception.GetType().Name)" 

    } 

    finally { 

        # This block always runs regardless of error occurrence 

        Write-Host "Finished performing math operations." 

    } 

}
      

Das folgende Bildschirmfoto zeigt das Ergebnis des Aufrufs dieser Funktion auf zwei Arten. Zuerst rufen wir sie mit gültigen Eingaben auf:

Perform-MathOperations -Num1 10 -Num2 2

Dann rufen wir es mit einer Eingabe auf, die zu einem Versuch führen wird, durch null zu teilen:

Perform-MathOperations -Num1 10 -Num2 0

Image

Fehlerbehebung bei Ihren Funktionen

Sie können Nachrichten anzeigen, die während der Funktionsausführung verschiedene Detailstufen bieten, indem Sie Write-output (oder Write-host), Write-Verbose und Write-Debug. Diese Informationen können Ihnen helfen, den Ausführungspfad Schritt für Schritt nachzuvollziehen, um unerwartetes Verhalten genau zu identifizieren.

Zum Beispiel zeigt der folgende Screenshot, wie wir unsere grundlegende Add-Numbers-Funktion überarbeiten könnten, um Fehlerbehebungsdetails bereitzustellen. Beachten Sie, dass standardmäßig der ausführliche Nachrichtenstrom nicht angezeigt wird, daher müssen wir -Verbose verwenden, wenn wir die Funktion aufrufen. 

      Add-Numbers -Number1 5 -Number2 10 -Verbose 

      
Image

Ähnlich werden Write-Debug Nachrichten standardmäßig nicht in der Konsole angezeigt, aber Sie können sie anzeigen lassen, indem Sie -Debug beim Ausführen der Funktion hinzufügen: 

Add-Numbers -Number1 5 -Number2 10 -Debug

Image

Best Practices

  • Gestalten Sie jede Funktion so, dass sie eine Aufgabe erfüllt. Dadurch sind sie einfacher zu testen, zu verwenden und zu warten.
  • Gestalten Sie Funktionen modular, damit sie in verschiedenen Skripten wiederverwendet werden können.
  • Geben Sie beim Verwenden von Parametern deren Standardwerte an.
  • Fügen Sie detaillierte Kommentare in Ihre Funktionen ein. Diese kommentarbasierte Hilfe erleichtert das Debuggen und die Wiederverwendung von Funktionen.
  • Lassen Sie Ihre Funktionen Objekte zurückgeben, anstatt formatierte Ausgaben zu erzeugen, um die Wiederverwendbarkeit zu verbessern.

Zusätzliches Beispiel

Die folgende Funktion veranschaulicht viele der zuvor diskutierten Fähigkeiten, einschließlich der Fehlerbehandlung:

      # Function: Backup-Files 

# Description: Backs up files from a source directory to a backup directory. 

function Backup-Files { 

    param ( 

        [Parameter(Mandatory = $true)] 

        [string]$SourcePath, # The directory containing the files to back up 

        [Parameter(Mandatory = $true)] 

        [string]$BackupPath, # The directory where files will be backed up 

        [string[]]$Extensions = @("*") # File extensions to back up (default: all files) 

    ) 

    # Check if the source path exists 

    if (-not (Test-Path -Path $SourcePath)) { 

        Write-Error "Source path '$SourcePath' does not exist." 

        return 

    } 

    # Create the backup directory if it does not exist 

    if (-not (Test-Path -Path $BackupPath)) { 

        Write-Output "Creating backup directory at '$BackupPath'..." 

        New-Item -ItemType Directory -Path $BackupPath | Out-Null 

    } 

    # Get files matching the specified extensions 

    foreach ($extension in $Extensions) { 

        $files = Get-ChildItem -Path $SourcePath -Filter "*.$extension" -File -ErrorAction SilentlyContinue 

        foreach ($file in $files) { 

            $destination = Join-Path -Path $BackupPath -ChildPath $file.Name 

            Write-Output "Backing up file: $($file.FullName) -> $destination" 

            Copy-Item -Path $file.FullName -Destination $destination -Force 

        } 

    } 

    Write-Output "Backup completed successfully." 

}
      

Wir können diese Funktion nutzen, um alle Dateien zu sichern oder nur ausgewählte Dateierweiterungen, wie hier gezeigt:

      Backup-Files -SourcePath "D:\Office\project" -BackupPath "D:\Backup" -Extensions @("csv", "txt") 

      
Image

Fazit

Funktionen in PowerShell bieten einen strukturierten Ansatz für das Scripting, der die Modularität, Wiederverwendbarkeit und Wartbarkeit verbessert. Fühlen Sie sich frei, mit all dem Beispielcode, der in diesem Artikel bereitgestellt wird, zu experimentieren. Wenn Sie beginnen, Ihre eigenen Funktionen zu erstellen, achten Sie darauf, die besten Praktiken für die Benennung und Verwendung zu übernehmen.

Teilen auf

Erfahren Sie mehr

Über den Autor

Asset Not Found

Tyler Reese

VP of Product Management, CISSP

Mit mehr als zwei Jahrzehnten in der Software-Sicherheitsbranche ist Tyler Reese bestens vertraut mit den sich schnell entwickelnden Identitäts- und Sicherheitsherausforderungen, denen Unternehmen heute gegenüberstehen. Derzeit ist er als Produktleiter für das Netwrix Identity and Access Management Portfolio tätig, wo seine Aufgaben die Bewertung von Markttrends, die Festlegung der Richtung für die IAM-Produktlinie und letztendlich die Erfüllung der Bedürfnisse der Endanwender umfassen. Seine berufliche Erfahrung reicht von IAM-Beratung für Fortune-500-Unternehmen bis hin zur Arbeit als Unternehmensarchitekt eines großen Direkt-an-Verbraucher-Unternehmens. Derzeit hält er die CISSP-Zertifizierung.