Validation 使用ScriptBlock作为强制的确定

Validation 使用ScriptBlock作为强制的确定,validation,function,powershell,Validation,Function,Powershell,我希望可以设置cmdlet,以便在参数值存在时使用环境变量,或者使用其他提示 function Test-Mandatory { [CmdletBinding()] param( [Parameter(Mandatory = { [string]::IsNullOrEmpty($Env:TEST_PARAM) })] [string] $foo = $Env:TEST_PARAM ) Write-Host $foo } 不幸的是,似乎无论我是否设置了$

我希望可以设置cmdlet,以便在参数值存在时使用环境变量,或者使用其他提示

function Test-Mandatory
{
  [CmdletBinding()]
  param(
    [Parameter(Mandatory = { [string]::IsNullOrEmpty($Env:TEST_PARAM) })]
    [string]
    $foo = $Env:TEST_PARAM
  )

  Write-Host $foo
}
不幸的是,似乎无论我是否设置了
$Env:TEST_PARAM
,cmdlet都会提示输入$foo

我可以重新进行验证以使用
[ValidateScript({snip})
,但是如果
$Env:TEST\u PARAM
不存在,我就不会再得到Powershell提示输入所需的值。我只会得到一个验证错误

所以这里有两个问题

  • 为什么我甚至可以将scriptblock分配给Mandatory,如果它看起来不受尊重的话
  • 在我指定的条件下,有没有一种简单的方法可以获得默认的PS提示行为

对于第二个问题,您始终可以验证脚本中的值。只需将环境变量的值设置为默认值。当我尝试使用
($foo-eq$null)
进行验证时,它不起作用,因此我将其切换为
($foo-eq“”)
。以下是我测试的一个示例,以获得您的要求:

function Test-Mandatory
{
  [CmdletBinding()]
  param(
    [string] $foo = $Env:TEST_PARAM
  )
begin {
    if ($foo -eq "") { 
        $foo = Read-Host "Please enter foo: "
    }
} #end begin
process {
  Write-Host $foo
} #end process
} #end function

至于强制性问题,我相信如果你指定一个默认值(即使它是空的),它将满足强制赋值。当它检查值是否存在时,因为它被赋值,强制检查为true,允许它继续。

值得注意的是,这并不像您所期望的那样工作……我希望$foo仅在$Env:TEST_参数不存在时才标记为强制

但是,即使存在$Env:TEST_PARAM,shell也会提示:(


仅供参考,以下是微软对此的看法:

“这不是一个真正的bug。脚本块是有效的属性参数- e、 g.否则ValidateScriptBlock将无法正常工作。
属性参数始终转换为参数类型。在 在强制的情况下,它需要一个bool,并且任何时候你转换一个 ScriptBlock到bool,您将得到$true的值。您从未调用 执行转换的脚本块。“


你是正确的,默认值会阻止
必需的
脚本块运行。我会给你一个“正确”的答案。a-ha..很好的答案。这正是我想要的。有趣的注意:转换。那么,这是否意味着
[参数(必需={…}]
无论脚本块返回什么,都会产生一个强制参数?
function Test-Mandatory
{
  [CmdletBinding()]
  param(
    [Parameter(Mandatory = { [string]::IsNullOrEmpty($Env:TEST_PARAM) })]
    [string]
    $foo
  )

if (!$PsBoundParameters.foo) { $foo = $Env:TEST_PARAM }

  Write-Host $foo
}