Es gibt hier einige gute Antworten, aber ich wollte noch auf ein paar andere Dinge hinweisen. Funktionsparameter sind tatsächlich ein Bereich, in dem PowerShell glänzt. Zum Beispiel können Sie benannte oder positionale Parameter in erweiterten Funktionen wie folgt haben:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[int] $Id
)
}
Dann könnten Sie es entweder aufrufen, indem Sie den Parameternamen angeben, oder Sie könnten einfach positionale Parameter verwenden, da Sie sie explizit definiert haben. Daher würden beide dieser Beispiele funktionieren:
Get-Something -Id 34 -Name "Blah"
Get-Something "Blah" 34
Das erste Beispiel funktioniert, obwohl Name
als zweites angegeben ist, weil wir den Parameternamen explizit verwendet haben. Das zweite Beispiel funktioniert jedoch basierend auf der Position, daher müsste Name
zuerst stehen. Wenn möglich, versuche ich immer, Positionen zu definieren, damit beide Optionen verfügbar sind.
PowerShell hat auch die Möglichkeit, Parametersätze zu definieren. Es verwendet dies anstelle von Methodenüberladung und ist wiederum sehr nützlich:
function Get-Something
{
[CmdletBinding(DefaultParameterSetName='Name')]
Param
(
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Name')]
[string] $Name,
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Id')]
[int] $Id
)
}
Jetzt nimmt die Funktion entweder einen Namen oder eine ID entgegen, aber nicht beides. Sie können sie positionell oder nach Namen verwenden. Da es sich um einen anderen Typ handelt, wird PowerShell das herausfinden. Daher würden all diese funktionieren:
Get-Something "Some Name"
Get-Something 23
Get-Something -Name "Some Name"
Get-Something -Id 23
Sie können auch zusätzliche Parameter den verschiedenen Parametersätzen zuweisen. (Das war offensichtlich ein ziemlich grundlegendes Beispiel.) Innerhalb der Funktion können Sie feststellen, welcher Parametersatz mit der Eigenschaft $PsCmdlet.ParameterSetName verwendet wurde. Zum Beispiel:
if($PsCmdlet.ParameterSetName -eq "Name")
{
Write-Host "Hier wird etwas mit dem Namen gemacht"
}
Dann gibt es noch die Parametervalidierung in PowerShell. Das ist eines meiner Lieblingsfeatures von PowerShell, und es macht den Code innerhalb Ihrer Funktionen sehr sauber. Es gibt zahlreiche Validierungen, die Sie verwenden können. Ein paar Beispiele sind:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidatePattern('^Some.*')]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[ValidateRange(10,100)]
[int] $Id
)
}
Im ersten Beispiel akzeptiert ValidatePattern einen regulären Ausdruck, der sicherstellt, dass der übergebene Parameter mit dem übereinstimmt, was Sie erwarten. Wenn nicht, wird eine intuitive Ausnahme geworfen, die Ihnen genau sagt, was falsch ist. In diesem Beispiel würde beispielsweise 'Something' gut funktionieren, aber 'Summer' würde die Validierung nicht bestehen.
ValidateRange stellt sicher, dass der Parameterwert zwischen dem von Ihnen erwarteten Bereich für eine ganze Zahl liegt. Also 10 oder 99 würden funktionieren, aber 101 würde eine Ausnahme auslösen.
Ein weiterer nützlicher Validator ist ValidateSet, mit dem Sie explizit ein Array akzeptabler Werte definieren können. Wenn etwas anderes eingegeben wird, wird eine Ausnahme ausgelöst. Es gibt auch andere, aber wahrscheinlich ist der nützlichste ValidateScript. Dies nimmt einen Skriptblock an, der zu $true ausgewertet werden muss, also sind Ihnen keine Grenzen gesetzt. Zum Beispiel:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidateScript({ Test-Path $_ -PathType 'Leaf' })]
[ValidateScript({ (Get-Item $_ | select -Expand Extension) -eq ".csv" })]
[string] $Path
)
}
In diesem Beispiel sind wir nicht nur versichert, dass $Path existiert, sondern auch, dass es eine Datei (im Gegensatz zu einem Verzeichnis) ist und eine .csv-Erweiterung hat. ($_ bezieht sich auf den Parameter, wenn Sie sich innerhalb Ihres Skriptblocks befinden.) Sie können auch viel größere, mehrzeilige Skriptblocks übergeben, wenn diese Ebene erforderlich ist, oder mehrere Skriptblocks wie ich hier. Es ist äußerst nützlich und sorgt für saubere Funktionen und intuitive Ausnahmen.
8 Stimmen
Du rufst einfach so an:
Test "ABC" "DEF"
2 Stimmen
Meiner bescheidenen Meinung nach zeigt die Tatsache, dass diese Frage und Antwort so viele positive Bewertungen haben, dass die aktuelle Implementierung.... nicht intuitiv ist.