这不起作用的原因是管道参数具有不同的值,具体取决于您是否处于Begin {}
, Process {}
, or End {}
堵塞。在某些时候,默认值会被评估,因此会抛出异常。这是我不喜欢那个特定黑客的原因之一。
合适的解决方案(我希望)
我非常喜欢它,所以我写了一篇关于它的博客文章所以我希望你觉得它有用。
function Validate-MandatoryOptionalParameters {
[CmdletBinding()]
param(
[Parameter(
Mandatory=$true
)]
[System.Management.Automation.CommandInfo]
$Context ,
[Parameter(
Mandatory=$true,
ValueFromPipeline=$true
)]
[System.Collections.Generic.Dictionary[System.String,System.Object]]
$BoundParams ,
[Switch]
$SetBreakpoint
)
Process {
foreach($param in $Context.Parameters.GetEnumerator()) {
if ($param.Value.Aliases.Where({$_ -imatch '^Required_'})) {
if (!$BoundParams[$param.Key]) {
if ($SetBreakpoint) {
$stack = Get-PSCallStack | Select-Object -Index 1
Set-PSBreakpoint -Line $stack.ScriptLineNumber -Script $stack.ScriptName | Write-Debug
} else {
throw [System.ArgumentException]"'$($param.Key)' in command '$($Context.Name)' must be supplied by the caller."
}
}
}
}
}
}
我认为这样做的最大优点是,无论您有多少参数或它们的名称是什么,它都会以相同的方式被调用。
关键是你只需为每个以以下开头的参数添加一个别名即可Required_
.
Example:
function f {
[CmdletBinding()]
param(
[Parameter(
ValueFromPipeline=$true
)]
[Alias('Required_Param1')]
$Param1
)
Process {
$PSBoundParameters | Validate-MandatoryOptionalParameters -Context $MyInvocation.MyCommand
}
}
根据我们的聊天对话和您的用例,我设置了一个断点而不是抛出。看起来它可能有用,但不确定。更多信息在帖子中。
也可作为GitHub要点(其中包括基于评论的帮助)。
我认为解决这个问题的唯一方法是检查进程块中的值。
Process {
if (!$a) {
throw [System.ArgumentException]'You must supply a value for the -a parameter.'
}
}
如果您控制脚本的调用,您可以使用powershell.exe -NonInteractive
并且应该抛出(或至少退出)而不是提示。
验证函数示例
function Validate-Parameter {
[CmdletBinding()]
param(
[Parameter(
Mandatory=$true , #irony
ValueFromPipeline=$true
)]
[object]
$o ,
[String]
$Message
)
Begin {
if (!$Message) {
$Message = 'The specified parameter is required.'
}
}
Process {
if (!$o) {
throw [System.ArgumentException]$Message
}
}
}
# Usage
Process {
$a | Validate-Parameter -Message "-a is a required parameter"
$a,$b,$c,$d | Validate-Parameter
}