about_Parameter_Sets
介绍了如何在高级函数中定义和使用参数集。
PowerShell 使用参数集,允许你编写可以针对不同方案执行不同操作的单个函数。 参数集使你能够向用户公开不同的参数。 另外,可以根据用户指定的参数返回不同的信息。 一次只能使用一个参数集。
以下要求适用于所有参数集。
如果某个参数未指定有参数集,则该参数属于所有参数集。
每个参数集必须具有唯一的参数组合。 如果可能,应该至少有一个唯一参数是必需的参数。
包含多个位置参数的参数集必须为每个参数定义唯一位置。 两个位置参数不能指定同一位置。
一个集内只有一个参数可以声明值为
ValueFromPipeline
的true
关键字。 多个参数可以定义值为ValueFromPipelineByPropertyName
的true
关键字。
备注
参数集的数量限制为 32 个。
定义了多个参数集时,CmdletBinding 属性的 DefaultParameterSetName
关键字将指定默认参数集。
当 PowerShell 无法根据提供给命令的信息确定所要使用的参数集时,它会使用默认参数集。 有关 CmdletBinding 属性的详细信息,请参阅 about_Functions_CmdletBindingAttribute。
若要创建参数集,必须为参数集中的每个参数指定 Parameter 属性的 ParameterSetName
关键字。 对于属于多个参数集的参数,请为每个参数集添加 Parameter 属性。
使用 Parameter 属性,可以为每个参数集采用不同的方式来定义参数。 例如,可以将某个参数定义为在一个集内是必需的,在另一个集内是可选的。 但是,每个参数集必须至少包含一个唯一参数。
未分配参数集名称的参数属于所有参数集。
以下示例函数统计一个文本文件中的行数、字符数和单词数。 使用参数,你可以指定要返回哪些值以及要度量哪些文件。 定义了四个参数集:
- 路径
- PathAll
- LiteralPath
- LiteralPathAll
function Measure-Lines {
[CmdletBinding(DefaultParameterSetName = 'Path')]
param (
[Parameter(Mandatory, ParameterSetName = 'Path', Position = 0)]
[Parameter(Mandatory, ParameterSetName = 'PathAll', Position = 0)]
[string[]]$Path,
[Parameter(Mandatory, ParameterSetName = 'LiteralPathAll', ValueFromPipeline)]
[Parameter(Mandatory, ParameterSetName = 'LiteralPath', ValueFromPipeline)]
[string[]]$LiteralPath,
[Parameter(ParameterSetName = 'Path')]
[Parameter(ParameterSetName = 'LiteralPath')]
[switch]$Lines,
[Parameter(ParameterSetName = 'Path')]
[Parameter(ParameterSetName = 'LiteralPath')]
[switch]$Words,
[Parameter(ParameterSetName = 'Path')]
[Parameter(ParameterSetName = 'LiteralPath')]
[switch]$Characters,
[Parameter(Mandatory, ParameterSetName = 'PathAll')]
[Parameter(Mandatory, ParameterSetName = 'LiteralPathAll')]
[switch]$All,
[Parameter(ParameterSetName = 'Path')]
[Parameter(ParameterSetName = 'PathAll')]
[switch]$Recurse
)
begin {
if ($All) {
$Lines = $Words = $Characters = $true
}
elseif (($Words -eq $false) -and ($Characters -eq $false)) {
$Lines = $true
}
}
process {
if ($Path) {
$Files = Get-ChildItem -Path $Path -Recurse:$Recurse -File
}
else {
$Files = Get-ChildItem -LiteralPath $LiteralPath -File
}
foreach ($file in $Files) {
$result = [ordered]@{ }
$result.Add('File', $file.FullName)
$content = Get-Content -LiteralPath $file.FullName
if ($Lines) { $result.Add('Lines', $content.Length) }
if ($Words) {
$wc = 0
foreach ($line in $content) { $wc += $line.split(' ').Length }
$result.Add('Words', $wc)
}
if ($Characters) {
$cc = 0
foreach ($line in $content) { $cc += $line.Length }
$result.Add('Characters', $cc)
}
New-Object -TypeName psobject -Property $result
}
}
}
每个参数集必须具有唯一的参数或唯一的参数组合。
Path
和 PathAll
参数集非常相似,但 All 参数对于 参数集是唯一的。PathAll
对于 LiteralPath
和 LiteralPathAll
参数集也是如此。 尽管 PathAll
和 LiteralPathAll
参数集都具有 All 参数,但 Path 和 LiteralPath 参数可以区分它们。
使用 Get-Command -Syntax
可显示每个参数集的语法。 但是,此命令不会显示参数集的名称。 以下示例显示每个参数集中可以使用哪些参数。
(Get-Command Measure-Lines).ParameterSets |
Select-Object -Property @{n='ParameterSetName';e={$_.Name}},
@{n='Parameters';e={$_.ToString()}}
ParameterSetName Parameters
---------------- ----------
Path [-Path] <string[]> [-Lines] [-Words] [-Characters] [-Recurse] [<CommonParameters>]
PathAll [-Path] <string[]> -All [-Recurse] [<CommonParameters>]
LiteralPath -LiteralPath <string[]> [-Lines] [-Words] [-Characters] [<CommonParameters>]
LiteralPathAll -LiteralPath <string[]> -All [<CommonParameters>]
示例使用 PathAll
参数集。
Measure-Lines test* -All
File Lines Words Characters
---- ----- ----- ----------
C:\temp\test\test.help.txt 31 562 2059
C:\temp\test\test.md 30 1527 3224
C:\temp\test\test.ps1 3 3 79
C:\temp\test\test[1].txt 31 562 2059
此示例使用了来自不同参数集的唯一参数。
Get-ChildItem -Path $PSHOME -LiteralPath $PSHOME
Get-ChildItem: Parameter set cannot be resolved using the specified named
parameters. One or more parameters issued cannot be used together or an
insufficient number of parameters were provided.
Path 和 LiteralPath 参数对于 cmdlet 的不同参数集是唯一的。Get-ChildItem
当这些参数在同一个 cmdlet 中一起运行时,会引发错误。 对于每个 cmdlet 调用,一次只能使用一个参数集。
自动变量 $PSCmdlet
提供 ParameterSetName 属性。
此属性包含正在使用的参数集的名称。 可以在函数中使用此属性来确定使用哪个参数集来选择特定于参数集的行为。
function Get-ParameterSetName {
[CmdletBinding(DefaultParameterSetName = 'Set1')]
param (
[Parameter(ParameterSetName = 'Set1', Position = 0)]
$Var1,
[Parameter(ParameterSetName = 'Set2', Position = 0)]
$Var2,
[Parameter(ParameterSetName = 'Set1', Position = 1)]
[Parameter(ParameterSetName = 'Set2', Position = 1)]
$Var3,
[Parameter(Position = 2)]
$Var4
)
"Using Parameter set named '$($PSCmdlet.ParameterSetName)'"
switch ($PSCmdlet.ParameterSetName) {
'Set1' {
"`$Var1 = $Var1"
"`$Var3 = $Var3"
"`$Var4 = $Var4"
break
}
'Set2' {
"`$Var2 = $Var2"
"`$Var3 = $Var3"
"`$Var4 = $Var4"
break
}
}
}
PS> Get-ParameterSetName 1 2 3
Using Parameter set named 'Set1'
$Var1 = 1
$Var3 = 2
$Var4 = 3
PS> Get-ParameterSetName -Var2 1 2 3
Using Parameter set named 'Set2'
$Var2 = 1
$Var3 = 2
$Var4 = 3