这里有一些很好的答案,但我想指出其他几件事。函数参数实际上是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还具有定义参数集的功能。它使用它代替方法重载,再次非常有用:
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接受一个正则表达式,以确保所提供的参数与您期望的参数匹配。如果不是,则会抛出一个直观的异常,告诉您确切的错误。因此,在该示例中,“某事”可以很好地工作,但“夏令时”不会通过验证。
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扩展名。($ _是在脚本块内部时指向的参数。)如果需要该级别,也可以传递更大的多行脚本块,或者像我在此处那样使用多个脚本块。这是非常有用的,并且可以提供出色的简洁功能和直观的异常。
Test "ABC" "DEF"