如何使用参数实施来处理添加的ScriptMethod成员?

时间:2015-10-19 23:46:18

标签: validation powershell object methods parameters

我有和$ object我想要内置函数。我似乎无法弄清楚如何对添加函数的参数强制执行强制规则。

强制规则适用于与对象无关的标准函数,但是当我测试对象并运行函数时,我可以执行所需的强制参数。

 $object | Add-Member -Name ProcessFiles -MemberType ScriptMethod -Value { 
    param(
        [Parameter(Mandatory=$true)]
        [String[]]$FILES
    ) 

这不会引发错误,它应该抱怨缺少参数。

$object.ProcessFiles()  

有什么神奇之处?有没有人有自定义对象ScriptMethod参数验证的示例代码?

1 个答案:

答案 0 :(得分:2)

这很有趣。我可以确认你看到的行为(使用PowerShell 5.0,但我想它在整个过程中都是一样的。)

我不能确切地说出为什么会发生这种情况,但它必须与调用代码的方式有关。

通过执行$object.ProcessFiles.Script.Ast.ParamBlock.Parameters.Attributes,您可以看到保留了Mandatory参数,它似乎只是被忽略了。

的变通方法

一个简单的测试

如果您不需要强制参数的所有功能(也就是说,您不关心它是否提示输入值),您只需测试并throw

$object | Add-Member -MemberType ScriptMethod -Name test -Value { 
    param(
        [String[]]
        $Files
    )

    if (!$Files) {
        throw [System.ArgumentException]'-Files is required.'
    }
}

更通用的东西

在调查这个问题时,我注意到[ScriptBlock]确实强制执行了这些属性,所以我想出了这个黑客:

$object | Add-Member -MemberType ScriptMethod -Name ProcessFiles -Value { 
    param(
        [String[]]
        $Files
    )

    & {
        param(
            [Parameter(Mandatory=$true)]
            [String[]]
            $Files
        )

        $Files
    } @PSBoundParameters
}

这是在ScriptMethod中创建一个脚本块,它接受相同的参数,然后在调用脚本块时将所有绑定参数作为参数传递给它。

我没有使用更复杂的参数声明对其进行测试,但它应该可以解决这个问题。

我认为主要的缺点是你需要两次编写param块。如果您在Add-Member调用之外创建脚本块,则可以避免这种情况;您可以创建一个将scriptblock作为参数的函数,然后使用AST解析它并以编程方式创建一个嵌入并执行原始脚本块的新脚本块。这可能有点矫枉过正;也许我会写一篇关于它的博客文章。