powershell 我如何Assert参数绑定将成功而没有副作用?

lymnna71  于 2023-01-13  发布在  Shell
关注(0)|答案(1)|浏览(132)

假设我有一个函数,其中注入了依赖项和一些参数,如下所示:

function Invoke-ACommandLaterOn
{
    param
    (
        # ...
        [string]   $CommandName,
        [object]   $PipelineParams,
        [object[]] $PositionalParams,
        [hashtable]$NamedParams
        # ...
    )

    Assert-ParameterBinding @PSBoundParameters
    # ...
    # Some complicated long-running call tree that eventually invokes 
    # something like
    # $PipelineParams | & $CommandName @PositionalParams @NamedParams
    # ...
}

我想立即Assert参数绑定到$CommandName成功了,这就是Assert-ParameterBinding要做的,但是我不确定如何实现Assert-ParameterBinding
当然,我可以尝试立即调用$CommandName,但在这种情况下,这样做会产生副作用,而这些副作用只有在其他一些长期运行的任务完成之后才会出现。
我如何Assert参数绑定到一个函数将成功而不调用该函数?

wvt8vs2t

wvt8vs2t1#

如果你这样做(在Assert-函数中)会怎样?

$cmd = Get-Command $CommandName
$meta = [System.Management.Automation.CommandMetadata]::new($cmd)
$proxy = [System.Management.Automation.ProxyCommand]::Create($meta)

$code = $proxy -ireplace '(?sm)(?:begin|process|end)\s*\{.*','begin{}process{}end{}'

$sb = [scriptblock]::Create($code)

$PipeLineParams | & $sb @PositionalParams @NamedParams

实际上,我不确定它是否能与位置参数一起工作,或者与两个不同的集合一起工作(我没有做太多测试)。

解释

我有几个想法。首先,参数绑定可能非常复杂。在管道调用的情况下,当命中不同的块时,绑定会发生不同的情况。
因此,让PowerShell来处理这个问题可能是一个好主意,方法是重新创建相同的函数,但函数体什么也不做。
所以我用内置的方法生成了一个代理函数,因为它处理了所有混乱的工作,然后残忍地替换了主体,这样它就不会调用原始函数。
理想情况下,您将进行一个遵循所有常规参数绑定过程的调用,但最终什么也没有完成。
将其 Package 在try/catch中或以其他方式测试错误应该是一个很好的测试,可以测试这是否是一个成功的调用。
这甚至可以处理动态参数。
可能有一些边缘情况下,这将不会完全工作,但我认为他们将是罕见的。
此外,ValidateScript属性和动态参数可能会产生副作用。

相关问题