这里有一些很好的答案,但我想指出其他一些事情。函数参数其实是 PowerShell 大放异彩的地方。例如,您可以在高级函数中使用命名参数或位置参数,如下所示:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[int] $Id
)
}
然后您可以通过指定参数名称来调用它,或者您可以只使用位置参数,因为您明确定义了它们。所以这两种方法都可以:
Get-Something -Id 34 -Name "Blah"
Get-Something "Blah" 34
即使Name 第二个提供,第一个示例仍然有效,因为我们明确使用了参数名称。第二个示例基于位置,因此Name 需要成为第一个。如果可能,我总是尝试定义位置,以便两个选项都可用。
PowerShell 还具有定义参数集的能力。它使用 this 代替方法重载,而且非常有用:
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
)
}
现在该函数将采用名称或 id,但不能同时采用两者。您可以按位置或按名称使用它们。由于它们是不同的类型,PowerShell 会弄清楚。所以所有这些都可以工作:
Get-Something "some name"
Get-Something 23
Get-Something -Name "some name"
Get-Something -Id 23
您还可以将其他参数分配给各种参数集。 (这显然是一个非常基本的示例。)在函数内部,您可以确定哪个参数集与 $PsCmdlet.ParameterSetName 属性一起使用。例如:
if($PsCmdlet.ParameterSetName -eq "Name")
{
Write-Host "Doing something with name here"
}
然后,在相关的旁注中,PowerShell 中还有参数验证。这是我最喜欢的 PowerShell 功能之一,它使函数内的代码非常干净。您可以使用许多验证。几个例子是:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidatePattern('^Some.*')]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[ValidateRange(10,100)]
[int] $Id
)
}
在第一个示例中,ValidatePattern 接受一个正则表达式,以确保提供的参数与您期望的匹配。如果没有,就会抛出一个直观的异常,告诉你到底哪里出了问题。因此,在该示例中,“Something”可以正常工作,但“Summer”无法通过验证。
ValidateRange 确保参数值在您期望的整数范围之间。所以 10 或 99 会起作用,但 101 会抛出异常。
另一个有用的是 ValidateSet,它允许您显式定义一个可接受值的数组。如果输入其他内容,将引发异常。还有其他的,但可能最有用的一个是ValidateScript。这需要一个必须评估为 $true 的脚本块,所以没有限制。例如:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidateScript({ Test-Path $_ -PathType 'Leaf' })]
[ValidateScript({ (Get-Item $_ | select -Expand Extension) -eq ".csv" })]
[string] $Path
)
}
在此示例中,我们确信 $Path 不仅存在,而且它是一个文件(与目录相反)并且具有 .csv 扩展名。 ($_ 指的是参数,当在您的脚本块中时。)如果需要该级别,您还可以传递更大的多行脚本块,或者像我在这里所做的那样使用多个脚本块。它非常有用,可以提供漂亮的干净功能和直观的异常。