使当前项($ _ / $ PSItem)可用于模块函数中的scriptblock参数

时间:2019-02-14 16:44:00

标签: powershell module

基本上,我正在尝试使以下“内联if语句”功能正常工作(credit here

Function IIf($If, $Then, $Else) {
    If ($If -IsNot "Boolean") {$_ = $If}
    If ($If) {If ($Then -is "ScriptBlock") {&$Then} Else {$Then}}
    Else {If ($Else -is "ScriptBlock") {&$Else} Else {$Else}}
}

使用PowerShell v5似乎对我不起作用并称呼它

IIf "some string" {$_.Substring(0, 4)} "no string found :("

出现以下错误:

You cannot call a method on a null-valued expression.
At line:1 char:20
+ IIf "some string" {$_.Substring(0, 4)} "no string found :("
+                    ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

因此,作为一个更普遍的问题,如何使$_可用于传递给函数的脚本块?

我尝试遵循this answer,但似乎是将其传递给单独的过程,这不是我想要的。

更新: 看来问题是我在模块中而不是直接在脚本/ PS会话中具有该功能。一种解决方法是避免将其放入模块中,但是我认为模块更具可移植性,因此我想找到一个解决方案。

1 个答案:

答案 0 :(得分:2)

虽然我对您的症状没有任何解释,但有两个更改值得进行:

  • 不要尝试直接分配给$_;它是在PowerShell的控制下的 automatic 变量,并不是要由用户代码设置的(即使它 可以工作,但不应依赖)。

    • 相反,使用ForEach-Object cmdlet通过其$_参数隐式设置-InputObject
  • 使用类型为 literals -is运算符,例如[Boolean],而不是类型为 names 的类型,例如"Boolean"

Function IIf($If, $Then, $Else) {
  If ($If) { 
    If ($Then -is [scriptblock]) { ForEach-Object -InputObject $If -Process $Then } 
    Else { $Then } 
  } Else {
    If ($Else -is [scriptblock]) { ForEach-Object -InputObject $If -Process $Else }
    Else { $Else }
  }
}