Tags: PowerShell, Troubleshooting
Beim Aufruf von Funktionen mit Parametern unterscheidet sich die PowerShell syntaktisch von den meisten anderen Sprachen. Der versehentliche Einsatz von Klammern und Kommata führt dann zu unerwünschten Ergebnissen. Diese kann man durch die Aktivierung des Strict-Mode und benannte Parameter vermeiden.
In fast allen gängigen Programmiersprachen übergibt man Argumente an eine Funktion, indem man diese in Klammern setzt und durch Kommata trennt, also nach dem Muster
func(a, b, c);
Dagegen will PowerShell hier weder Klammern noch Kommata, sondern nur Leerzeichen zwischen den Parametern. Verwendet man trotzdem die weit verbreitete Syntax, dann führt dies zu unerwarteten Ergebnissen. Dies sei anhand der Funktion test-func veranschaulicht, die 3 Parameter definiert:
Ruft man sie nun mit
test-func("Peter", 1, "mail@mymail.com")
auf, dann erhält man dieses Ergebnis:
Arg1: Peter 1 mail@mymail.com, Arg2: 0, Arg3:
Alle drei an die Funktion übergebenen Werte finden sich nun in der Variablen $Name, während $ID und $Email auf 0 bzw. leer bleiben.
Interpretation des Parameters als Array
Die Erklärung dafür lautet, dass PowerShell den Klammerausdruck im obigen Beispiel als Array interpretiert, das es dem ersten Parameter $Name zuschlägt. Die beiden anderen gehen leer aus.
Das gleiche Ergebnis erhält man auch, wenn man die Klammern weglässt und anstelle der Leerzeichen ein Komma als Trenner zwischen den Argumenten verwendet:
test-func "Peter", 1, "mail@mymail.com"
Die Gefahr für falsche Aufrufe erhöht sich dadurch, dass PowerShell bei Methoden von .NET-Klassen bzw. PowerShell-Objekten die Argumente sehr wohl in Klammern erwartet, aber eben nicht bei Funktionen. Hier ein Beispiel für einen Methoden-Aufruf bei einer String-Operation:
("Hallo Welt").split("l ", 2)
Strict-Mode
Schützen kann man sich gegen das falsche Aufrufen von functions nach dem Muster von Methoden, indem in einem Script den strict-Mode aktiviert:
Set-StrictMode -Version Latest
Der Parameter Version unterstützt neben Latest noch die Werte 1, 2, oder 3.
Aufruf mit benannten Parametern
Eine weitere Fehlerquelle beim Aufruf von Funktionen kann die Reihenfolge der Parameter sein. Im obigen Beispiel gibt die Definition der function nicht explizit die Position der Parameter durch das dafür vorgesehene Keyword vor. Daher muss man die Parameter beim Aufruf in der Reihenfolge anordnen, in der sie definiert wurden.
Es leuchtet ein, dass
test-func "mail@mymail.com" 1 "Peter"
aufgrund der falschen Zuordnung von Werten zu $Name und $Email zu unerwünschten Ergebnissen führt.
Einen gewissen Schutz gegen eine falsche Abfolge der Argumente bietet die Deklaration von $ID als integer, so dass an der 2. Position keiner der beiden Strings stehen kann, ohne dass es eine Fehlermeldung setzt.
Eine gute Vorbeugung gegen derartige Fehler besteht darin, eine Funktion mit benannten Parametern aufzurufen. In diesem Fall spielt die Reihenfolge dann keine Rolle mehr, und die Versuchung, Klammern zu verwenden, ist dann auch nicht mehr gegeben.
Im unserem Beispiel würde das so aussehen:
test-func -Name "Peter" -ID 1 -Email "mail@mymail.com"
Auch wenn dies nach mehr Tipparbeit aussieht, so fällt diese in der Praxis nicht ins Gewicht, weil PowerShell die Eingabe der Parameternamen durch die automatische Vervollständigung unterstützt.
Explizite Positionsparameter
Eine weitere Eigenheit von PowerShell-Funktionen besteht darin, dass die Festlegung der Position für einen Parameter automatisch dazu führt, dass man für alle anderen den Namen angeben muss.
Wenn in unserem Beispiel der Parameter $Email so
[Parameter(Position=2)]
[string]$Email
definiert wird, dann sind beim Aufruf die Namen der Parameter $Name und $ID erforderlich. Anderfalls wirft PowerShell einen Fehler aus.
Wenn man jedoch die einfache Variante mit den impliziten Positionsparametern bevorzugt, dann kann man im Zweifel die korrekte Reihenfolge mit Get-Help anzeigen.
In unserem Beispiel sähe das so aus:
Get-Help test-func
Täglich Know-how für IT-Pros mit unserem Newsletter
Verwandte Beiträge
- Welche lokalen Gruppenrichtlinien sind auf dem Rechner aktiviert?
- Resolve-DnsName: nslookup für PowerShell
- Windows-Sicherheit öffnet sich nicht: Store-App mit PowerShell zurücksetzen
- Updates in WSUS importieren mit Internet Explorer oder PowerShell
- WSUS-Speicherplatz zurückgewinnen: Alte und ersetzte Updates löschen
Weitere Links