从 psm 函数的脚本块中定义的获取变量

Get-Variable defined in a scriptblock from a psm function

我有如下一段代码:

$x = 'xyz'
& {
    $y = 'abc'
    foo
}

foo函数在脚本块启动前导入的foo.psm1模块中定义。

foo 函数中,我调用 Get-Variable 显示 x 但它没有显示 y。我尝试使用 -Scope 参数:LocalScriptGlobal0 - 这是我从文档中理解的本地范围,1 - 这是父作用域。

如何在 foo 函数中获取 y 变量?

我不是在寻找解决方案,例如将其作为参数传递。我想要 Get-Variable 的东西,但遗憾的是由于某种原因它没有看到它。

UP

根据收到的评论,可能需要更多上下文。

假设 foo 收到一个使用 $using: 语法的 ScriptBlock

$x = 'xyz'
& {
    $y = 'abc'
    foo -ScriptBlock {
        Write-Host $using:x
        Write-Host $using:y
    }
}

我'mining'这些变量如下:

$usingAsts = $ScriptBlock.Ast.FindAll( { param($ast) $ast -is [System.Management.Automation.Language.UsingExpressionAst] }, $true) | ForEach-Object { $_ -as [System.Management.Automation.Language.UsingExpressionAst] }
foreach ($usingAst in $usingAsts) {
    $varAst = $usingAst.SubExpression -as [System.Management.Automation.Language.VariableExpressionAst]
    $var = Get-Variable -Name $varAst.VariablePath.UserPath -ErrorAction SilentlyContinue
}       

这就是我使用 Get-Variable 的方式,在上述情况下,无法找到 y

模块 运行 在它们自己的 范围域 中(又名 会话状态 ),这意味着它们通常 看到调用者的变量-除非(模块外部)调用者运行直接在全局范围内。

  • 有关 PowerShell 范围的概述,请参阅 的底部部分。

但是,假设您将模块中的函数定义为 advanced one, there is a way to access the caller's state, namely via the automatic $PSCmdlet variable

这是一个简化的示例,使用通过 New-Module cmdlet 创建的 dynamic 模块:

# Create a dynamic module that defines function 'foo'
$null = New-Module {
  function foo {    
    # Make the function and advanced (cmdlet-like) one, via
    # [CmdletBinding()].
    [CmdletBinding()] param()
    # Access the value of variable $bar in the
    # (module-external) caller's scope.
    # To get the variable *object*, use:
    #    $PSCmdlet.SessionState.PSVariable.Get('bar')
    $PSCmdlet.GetVariableValue('bar')
  }
}

& {
  $bar = 'abc'
  foo
}

以上内容根据需要逐字输出 abc