PowerShell Skripting Best Practices Leitfaden

Was

Dieser Artikel bietet einen umfassenden Leitfaden zu Best Practices im PowerShell-Scripting mit Fokus auf Code-Struktur, Ausgabeformatierung, Fehlerbehandlung, Leistungsoptimierung und Sicherheitsmaßnahmen.

Warum

Die Einhaltung von Best Practices im PowerShell-Scripting stellt sicher, dass Skripte lesbar, wartbar, sicher und performant sind. Dadurch werden technische Schulden reduziert, die Zusammenarbeit verbessert und Risiken in Produktionsumgebungen minimiert.

Wie

Tool- und Controller-Design

Entscheiden Sie, ob Sie ein ‚Tool‘ oder einen ‚Controller‘ schreiben

  • Tool: Wiederverwendbare Funktionen/Module.
  • Controller: Automatisiert eine spezifische Aufgabe, nicht zur Wiederverwendung gedacht.

Machen Sie Ihren Code modular

  • Verwenden Sie Funktionen und Skriptmodule für maximale Wiederverwendbarkeit.

Verwenden Sie standardisierte Namenskonventionen

  • Verwenden Sie das Verb-Nomen-Format mit genehmigten PowerShell-Verben (Get-Verb).

Standardisieren Sie Parameternamen

  • Nutzen Sie Namen wie $ComputerName anstelle eigener Präfixe.

Tools geben Rohdaten aus

  • Tools sollten minimal verarbeitete Daten für Flexibilität ausgeben.

Controller geben formatierte Daten aus

  • Controller können benutzerfreundliche Berichte ausgeben.

Beispiel

function Get-DiskInfo {
    param ([string]$ComputerName)
    Get-WmiObject Win32_LogicalDisk -ComputerName $ComputerName
}

Das Rad nicht neu erfinden

Verwenden Sie integrierte Cmdlets wie Test-Connection statt eigener Ping-Funktionen.

# Bevorzugt
Test-Connection $ComputerName -Quiet

Schreiben von Parameterblöcken

Immer Hilfe schreiben

Fügen Sie kommentarbasierte Hilfe mit .SYNOPSIS, .DESCRIPTION und mindestens einem .EXAMPLE hinzu.

function Test-Help {
    <#
        .SYNOPSIS
            Zeigt eine korrekte Hilfedokumentation.
        .EXAMPLE
            Test-Help -MandatoryParameter "Beispiel"
            Führt die Test-Help-Funktion mit einem Pflichtparameter aus.
    #>
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [Alias("MP")]
        [String]$MandatoryParameter
    )
}

Verwenden Sie [CmdletBinding()]

Aktiviert gemeinsame Parameter wie -Verbose, -Debug, -ErrorAction.

Unterstützen Sie -WhatIf und -Confirm

Für befehlsverändernde Aktionen SupportsShouldProcess verwenden.

[CmdletBinding(SupportsShouldProcess, ConfirmImpact = "Medium")]
param ([switch]$Force)

Parameter stark typisieren

Definieren Sie stets Parametertypen für Validierung und Klarheit.

param (
    [string]$Name,
    [int]$Count
)

[switch] korrekt verwenden

  • Standardwert ist $false.
  • Logisch als Boolean verwenden, keine drei Zustände simulieren.

Ausgabeformatierung

Write-Host vermeiden, wenn nicht nötig

Verwenden Sie je nach Bedarf Write-Verbose, Write-Debug oder Write-Output.

Write-Progress für Fortschrittsanzeigen nutzen

Write-Progress -Activity "Verarbeitung" -Status "50% abgeschlossen" -PercentComplete 50

Formatdateien für benutzerdefinierte Objekte verwenden

Definieren Sie .format.ps1xml-Dateien statt Inline-Formatierung.

Nur einen Typ gleichzeitig ausgeben

Verwenden Sie [OutputType()] und vermeiden Sie gemischte Objekttypen.


Fehlerbehandlung Best Practices

-ErrorAction Stop mit Cmdlets verwenden

Erzwingen Sie Abbruchfehler für try-catch.

try {
    Get-Item "C:\InvalidPath" -ErrorAction Stop
} catch {
    Write-Warning "Element nicht gefunden."
}

$ErrorActionPreference bei Nicht-Cmdlets nutzen

Temporär auf 'Stop' setzen bei riskanten Operationen.

Flags und $? vermeiden

Stattdessen strukturierte try-catch-Blöcke nutzen.

$Error[0] oder $_ sofort im catch kopieren

catch {
    $errorDetails = $_
    Write-Error "Ein Fehler ist aufgetreten: $($errorDetails.Exception.Message)"
}

Leistungsoptimierung

PERF-01 Leistung nur messen, wenn nötig

Verwenden Sie Measure-Command für Benchmarking.

Measure-Command {
    foreach ($item in $data) { Process-Item $item }
}

PERF-02 Balance zwischen Leistung und Lesbarkeit

  • Kleine Datenmengen: Lesbarkeit vorziehen.
  • Große Datenmengen: Streaming oder .NET-Methoden in Betracht ziehen.

Leserlich, aber weniger performant:

$content = Get-Content -Path file.txt
foreach ($line in $content) {
    Do-Something -Input $line
}

Performance-optimiert:

Get-Content -Path file.txt | ForEach-Object {
    Do-Something -Input $_
}

Hochperformant mit .NET:

$sr = New-Object System.IO.StreamReader "file.txt"
while ($sr.Peek() -ge 0) {
    $line = $sr.ReadLine()
    Do-Something -Input $line
}

PERF-03 Sprachfeatures bevorzugen

  • Sprachkonstrukte (foreach) > .NET-Methoden > Skripte > Cmdlets/Pipeline
  • Immer messen, bevor optimiert wird.

Sicherheits-Best Practices

Immer PSCredential für Anmeldedaten verwenden

Keine Klartext-Passwörter. [Credential()] als Parameter nutzen.

param (
    [System.Management.Automation.PSCredential]
    [System.Management.Automation.Credential()]
    $Credential
)

Bei API-Übergaben:

$Insecure.SetPassword($Credential.GetNetworkCredential().Password)

SecureString für sensible Daten nutzen

Sicher abfragen und verschlüsselt speichern.

$Secure = Read-Host -Prompt "Geben Sie sichere Daten ein" -AsSecureString

Sicher in Klartext umwandeln:

$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Secure)
$PlainText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)

Anmeldedaten sicher speichern

Export-CliXml verwenden.

Get-Credential | Export-CliXml -Path C:\secure\cred.xml
$Credential = Import-CliXml -Path C:\secure\cred.xml

Verschlüsselte Zeichenketten speichern

ConvertFrom-SecureString -SecureString $Secure | Out-File -Path "${Env:AppData}\secure.bin"
$Secure = Get-Content -Path "${Env:AppData}\secure.bin" | ConvertTo-SecureString

Fazit

Durch die Befolgung dieser PowerShell-Best-Practices in den Bereichen Design, Dokumentation, Ausgabe, Fehlerbehandlung, Leistung und Sicherheit erstellen Sie robuste, wartbare und effiziente Skripte. Streben Sie stets ein Gleichgewicht zwischen Lesbarkeit, Performance und Sicherheit an, um hochwertige Automatisierungslösungen zu liefern.

タイトルとURLをコピーしました