问题: 试图更改显示的错误消息,说他们需要cmdlet参数包含“ -passed,-warning或-failed”,或者不关心这三个消息是否丢失并写消息(假定在此处) 。
说明: 创建了一个函数,该函数接受三个参数:消息,第二消息和消息状态(通过, 失败,警告)。我收到默认错误消息“无法使用指定的名称解析参数 参数。”无论您是否通过以下方式传递消息,都会发生这种情况:
PS C:\> Write-Message;
Write-Message : Parameter set cannot be resolved using the specified named parameters.
...
//or
PS C:\> Write-Message -Message "Hello World";
但是,如果您要输入'status'参数,它将可以正常使用:
PS C:\> Write-Message -Message "Hello World" -Passed;
Hello World
(“ Hello World”在这里应该是绿色,但是Stack Overflow还没有该功能)
有关功能:
Function Write-Message {
param(
[string]$Message,
[string]$MessageTwo,
[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName = $true, ParameterSetName ="Passed")][switch]$Passed,
[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName = $true, ParameterSetName ="Warning")][switch]$Warning,
[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName = $true, ParameterSetName ="Failed")][switch]$Failed
);
$NewLineNeeded = [string]::IsNullOrEmpty($MessageTwo);
if ($Passed){
$color = 'green';
}
if($Warning){
$color = 'yellow';
}
if($Failed){
$color = 'red';
}
if($Passed -or $Warning -or $Failed){
if(!$NewLineNeeded){
Write-Host $MessageOne -NoNewline;
Write-Host $MessageTwo -ForegroundColor $color;
} else {
Write-Host $Message -ForegroundColor $color;
}
}
}
答案 0 :(得分:3)
添加一个“默认”参数集来解决此问题。实际上,您不必使用代码中的参数集,因此即使使用“默认”之类的代码也无需更改代码即可使用。在编写更复杂的cmdlet时遇到了这种麻烦,我在其中将参数集用于互斥参数,但是某些参数与参数集无关。
Function Write-Message {
[CmdletBinding(DefaultParameterSetName="Default")]
Param(
...
当仅使用不带参数集的参数,并且在cmdlet中也定义了参数集时,Powershell似乎对正在使用哪个参数集感到困惑。
您只需要满足以下所有条件,即可:
如mklement0's answer中所述,以及有关发生的情况的一些幕后信息,这可能是一种错误,并且此解决方案是解决方法。
答案 1 :(得分:3)
为Bender the Greatest' effective solution and helpful explanation补充更多的背景信息:
未通过其[Parameter()]
属性标记为至少属于一个参数集的参数:
被隐含地视为所有定义的参数集的一部分。
分配了自动__AllParameterSets
参数集。
您可以使用Write-Message
函数来进行以下验证:
(Get-Command Write-Message).Parameters.GetEnumerator() |
Select-Object @{ n='ParameterName'; e = { $_.Key } },
@{ n='ParameterSets'; e = { $_.Value.ParameterSets.GetEnumerator().ForEach('Key') } }
以上结果(省略了常用参数):
ParameterName ParameterSets
------------- -------------
Message __AllParameterSets
MessageTwo __AllParameterSets
Passed Passed
Warning Warning
Failed Failed
# ...
重要:将参数标记为属于参数集后,它仅 属于该参数集,如果也需要属于其他人,则需要多个,分别的[Parameter(ParameterSetName = '...')]
属性-每个感兴趣的参数集一个。
当使用给定的一组参数值调用给定的函数或脚本时,PowerShell会尝试明确推断要应用的参数集,并报告$PSCmdlet.ParameterSetName
中的选定参数集。 / p>
如果不能明确地推断单个参数集,则会发生语句终止错误;也就是说,从根本上来说该函数的调用会失败(但是默认情况下会继续执行脚本)。 发生这种情况有两个原因之一:
相互排斥的参数:指定了属于不同参数集的参数(没有至少一个相关参数集相同的参数)。
传递了一个模糊的参数组合:尚不清楚要选择哪个参数集,因为可以应用多个参数。
在两种情况下,错误消息都是相同的:
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.
顺便说一句:如果仅指定参数名称的前缀(PowerShell通常支持),并且前缀不明确,即与 multiple 参数;例如-Out
含糊不清,因为它与-OutVariable
和-OutBuffer
都匹配:
Parameter cannot be processed because the parameter name 'Out' is ambiguous. Possible matches include: -OutVariable -OutBuffer.
如果您指定 no 参数或仅指定未明确标记为属于参数集和的参数,则尚未定义默认参数集,PowerShell将选择__AllParameterSets
集并将其反映在$PSCmdlet.ParameterSetName
中。
但是,令人惊讶的是,只有在只有一个明确定义的参数集的情况下,这才起作用。
具有两个或多个显式参数集-如您的情况-PowerShell认为这种情况不明确并报告错误。
this GitHub issue中讨论了这种令人惊讶的行为。
如Bender的答案所示,解决方法是通过上方的[CmdletBinding()]
属性来定义一个默认参数设置。 param(...)
块;例如: [CmdletBinding(DefaultParameterSetName='Default')]
此参数集是隐式创建的,可以自由选择其名称;无需将实际参数标记为属于它。
现在,当您不指定参数或仅指定没有显式参数集标记的参数时,调用成功,并且$PSCmdlet.ParameterSetName
反映默认参数集的名称。