这里有一些很好的答案,但我想指出一些其他的事情。函数参数实际上是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。第二个例子基于位置,所以Name需要放在第一位。在可能的情况下,我总是尝试定义位置,以便两种选项都可用。
PowerShell还具有定义参数集的能力。它使用这个来代替方法重载,同样非常有用:
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扩展名。($_指的是参数,当在你的脚本块。)如果需要,您还可以传入更大的多行脚本块,或者像我在这里所做的那样使用多个脚本块。它非常有用,可以生成非常干净的函数和直观的异常。