我并不是说这个问题听起来太可爱了,但这确实是手头的问题。考虑在 $env:PSModulePath 下安装的 PowerShell 模块 Test.psm1 中定义的以下两个函数:

function Start-TestAsync
{
    [CmdletBinding()]
    param([ScriptBlock]$Block, [string]$Name = '')
    Start-Job { Start-Test -Name $using:Name -Block $using:Block }
}

function Start-Test
{
    [CmdletBinding()]
    param([ScriptBlock]$Block, [string]$Name = '')
    # do some work here, including this:
    Invoke-Command -ScriptBlock $Block
}

导入模块后,我就可以运行同步函数了...
PS> Start-Test -Name "My Test" -Block { ps | select -first 9 }

...它显示来自 Get-Process 的适当输出。

但是,当我尝试运行异步版本时...
PS> $testJob=Start-TestAsync -Name "My Test" -Block { ps | select -first 9 }

...然后查看其输出...
PS> Receive-Job $testJob

...它只是将参数引入 Start-Test 函数失败,报告它无法将 String 转换为 ScriptBlock。因此,-Block $using:Block 传递的是 String 而不是 ScriptBlock!

经过一些实验,我确实找到了解决方法。如果我修改 Start-Test 以使 $Block 参数的类型为 [string] 而不是 [ScriptBlock] -- 然后将该字符串转换回块以提供给 Invoke-Command ...
function Start-Test
{
    [CmdletBinding()]
    param([string]$Block, [string]$Name = '')
    $myBlock = [ScriptBlock]::Create($Block)
    Invoke-Command -ScriptBlock $myBlock
}

当我从上面运行相同的命令时,我会得到正确的结果:
PS> $testJob=Start-TestAsync -Name "My Test" -Block { ps | select -first 9 }
PS> Receive-Job $testJob
using 范围在我的初始示例中是否正常工作(将 ScriptBlock 转换为字符串)?关于它的有限文档( about_Remote_Variablesabout_Scopes )提供的指导很少。
最终,当 $Block 参数输入为 [ScriptBlock] 时,有没有办法让 Start-Test 工作?

最佳答案

这显然是设计使然:https://connect.microsoft.com/PowerShell/feedback/details/685749/passing-scriptblocks-to-the-job-as-an-argument-cannot-process-argument-transformation-on-parameter

解决方法(来自上面的链接)是使用 [ScriptBlock]::Create() :



这将是您的解决方法(如您所见):

function Start-TestAsync
{
    [CmdletBinding()]
    param([ScriptBlock]$Block, [string]$Name = '')
    Start-Job { Start-Test -Name $using:Name -Block $using:Block }
}

function Start-Test
{
    [CmdletBinding()]
    param($Block, [string]$Name = '')
    # do some work here, including this:
    $sb = [ScriptBlock]::Create($Block)
    Invoke-Command -ScriptBlock $sb
}

关于powershell - 什么时候 ScriptBlock 不是 ScriptBlock?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25728616/

10-13 07:02