使用Powershell自省查找作为参数传递的函数的名称?

时间:2018-11-05 00:12:36

标签: function powershell introspection

说我是passing a function as a parameter,有没有办法通过Powershell中的自省找出传递的函数的名称?还是我只需要将其与其余参数一起传递?

(不调用有问题的函数)

1 个答案:

答案 0 :(得分:1)

链接的问题尝试通过 name 作为 string 传递函数,在这种情况下,答案很明显:参数本身就是函数名。

如果通过了 script块,则可以使用以下技术:

function get-ScriptBlockCommandName {

  param(
   [scriptblock] $ScriptBlock,
   [switch] $Expand 
  )

  # Using the script block's AST, extract the first command name / path token.
  $commandName = $ScriptBlock.Ast.EndBlock.
    Statements[0].PipelineElements.CommandElements[0].Extent.Text

  # Expand (interpolate) the raw name, if requested.
  if ($Expand) {
    $commandName = $ExecutionContext.InvokeCommand.ExpandString($commandName) 
  }

  # Remove outer quoting, if present.
  if ($commandName -match '^([''"])(.+)\1$') {
    $commandName = $Matches[2]
    if ($Matches[1] -eq "'") { $commandName = $commandName -replace "''", "'" }
  } 

  # Output
  $commandName

}

该函数返回从脚本块内部调用的(第一个)命令名称/路径。

注意事项

  • 如果将表达式(例如1 + 2)作为脚本块内的第一条语句传递,则会发生错误。

  • 仅分析 first 命令(并返回其命令名称/路径),而在脚本块中可以放置多少条语句没有限制。

  • 默认情况下,如果命令名/路径是由变量/其他命令构造的,则这些命令不会扩展(内插),因为这样做会导致执行命令;要选择扩展,请使用-Expand开关。

示例调用:

PS> get-ScriptBlockCommandName { foo -bar baz -more stuff }
foo

这也适用于带引号的名称/路径(请注意,然后必须使用&来调用命令):

PS> get-ScriptBlockCommandName { & '/dir name/foo' -bar baz -more stuff }
/dir name/foo

但是,为避免潜在的不必要的命令执行,命令名称/路径按原样返回 ,并带有变量引用和子表达式未扩展
您可以选择通过传递-Expand来扩展它们:

PS> get-ScriptBlockCommandName { & "$HOME/scripts/foo.ps1" -bar baz  } -Expand
C:/Users/jdoe/scripts.ps1  # e.g.