Powershell -从另一个脚本块的AST创建动态参数

djp7away  于 2023-06-06  发布在  Shell
关注(0)|答案(1)|浏览(143)

我有一个动态加载的PowerShell脚本块,它接受多个参数(包括Mandatory,type,default value,...)。我还有一个函数,它有自己的参数集,在内部,它调用脚本块。脚本块是基于其他参数动态加载的,我希望允许用户将参数传递给我的函数并将它们转发到脚本块。为此,我想从脚本块中读取可能的参数,我可以使用$block.Ast.ParamBlock.Parameters完成,然后使用DynamicParam为我的函数创建匹配的参数。

示例:

脚本块:

$block = {
  param([Parameter(Mandatory)][string]$test = 10)
  echo $test
}

功能:

function Fn {
  param($FnParam1, $FnParam2)

  DynamicParam {
    // what to write here
  }

  & $block // how to efficiently forward the parameters here?
}

应该可以像这样调用Fn

Fn -FnParam1 value -FnParam2 value -test 20

但是,DynamicParam是使用RuntimeDefinedParameter和相关类创建的,脚本块的AST返回Management.Automation.Language.ParameterAst和来自同一名称空间的其他示例。我可以通过逐个节点转换AST来手动创建DynamicParam参数,但似乎应该有一种更简单的方法来自动转换这些参数。

wfsdck30

wfsdck301#

我知道这是旧的,但不清楚是否有人真的回答了这个问题。既然我必须为自己的一个项目做这件事,我想我会插话。
首先,这是绝对可以做到的,尽管可能有点棘手。主cmdlet上需要一个可用于触发dynamicparam块的“trigger”参数。接下来需要的是要显示的参数的详细信息。虽然理论上这可以在运行时收集,但我建议不要这样做,因为它可能是开销密集型的,导致当用户尝试Tab完成时shell的长时间暂停,或者在用户执行之前进程没有完成。
我最近不得不自己为我正在构建的模块计算这一点。主模块利用仅在模块的私有范围中可见的“嵌套模块”。我的主cmdlet需要从嵌套模块调用一个cmdlet,沿着需要任何参数。
因此,解决性能问题,我将所有的“嵌套”模块放在一个特定的文件夹中,尽管您也可以使用列表中的特定过滤器。在导入过程中,我使用AST和ParameterAST子类来清点参数和符号(参数块、验证块、对象类、参数名等)。每个cmdlet的数据存储在数组中。主cmdlet有一个主要的伪静态定义参数,即“trigger”,它允许对嵌套模块中的cmdlet名称进行制表符补全。我通过一个动态生成的Enum来填充它,这样我就可以将它用作参数的类型,并注册一个参数完成器。一旦用户指定了要调用的子cmdlet,DynamicParam块将触发并筛选导入时收集的数组。然后,收集的参数详细信息将转换为对象,并提供给创建所需参数的“New-DynamicParameter”cmdlet。
我在我的博客上写了关于所有元素的更详细的内容,如果你想了解更多的东西-https://mer-bach.com/2023/05/10/promoting-external-parameters/

相关问题