【问题标题】:Powershell - how to pre-evaluate variables in a scriptblock for Start-JobPowershell - 如何为 Start-Job 预先评估脚本块中的变量
【发布时间】:2013-11-19 00:31:27
【问题描述】:

我想在 Powershell 中使用后台作业。

如何在 ScriptBlock 定义时评估变量?

$v1 = "123"
$v2 = "asdf"

$sb = {
    Write-Host "Values are: $v1, $v2"
}

$job = Start-Job -ScriptBlock $sb

$job | Wait-Job | Receive-Job

$job | Remove-Job

我打印了 $v1 和 $v2 的空值。我怎样才能让它们在脚本块中评估(传递给),然后再传递给后台作业?

【问题讨论】:

    标签: powershell background jobs start-job scriptblock


    【解决方案1】:

    将值声明为脚本块中的参数,然后使用-ArgumentList 传递它们

    $v1 = "123"
    $v2 = "asdf"
    
    $sb = {
        param
        (
            $v1,
            $v2
        )
        Write-Host "Values are: $v1, $v2"
    }
    
    $job = Start-Job -ScriptBlock $sb -ArgumentList $v1, $v2
    
    $job | Wait-Job | Receive-Job
    
    $job | Remove-Job
    

    【讨论】:

      【解决方案2】:

      我不在电脑前进行验证,但这应该可以:

      $sb = {
          param($p1,$p2)
          Write-Host "Values are: $p1, $p2"
      }
      
      $job = Start-Job -ScriptBlock $sb -ArgumentList $v1,$v2
      

      我会在上班时仔细检查。

      【讨论】:

        【解决方案3】:

        一种方法是使用 [scriptblock]::create 方法通过使用局部变量的可扩展字符串创建脚本块:

        $v1 = "123"
        $v2 = "asdf"
        
        $sb = [scriptblock]::Create("Write-Host 'Values are: $v1, $v2'")
        
        $job = Start-Job -ScriptBlock $sb
        

        另一种方法是在 InitializationScript 中设置变量:

        $Init_Script = {
        $v1 = "123"
        $v2 = "asdf"
        }
        
        $sb = {
            Write-Host "Values are: $v1, $v2"
        }
        
        $job = Start-Job -InitializationScript $Init_Script -ScriptBlock $sb 
        

        第三种选择是使用 -Argumentlist 参数:

        $v1 = "123"
        $v2 = "asdf"
        
        $sb = {
            Write-Host "Values are: $($args[0]), $($args[1])"
        }
        
        $job = Start-Job  -ScriptBlock $sb -ArgumentList $v1,$v2
        

        【讨论】:

        • 很好地使用-InitializationScript,我不知道那个。
        • 在这里评论以防有人正在寻找Register-ScheduledJob 抱怨-ScriptBlock 参数中的变量的答案。看到的错误是无法将参数绑定到参数“服务器”,因为它是一个空字符串。并解决它,我使用$script = [ScriptBlock]::Create("") 然后Register-ScheduledJob -ScriptBlock $script 并通过使用Get-ScheduledJob | Select * 确认工作
        • [scriptblock]::Create - 注意:您可以通过转义变量来阻止变量求值。例如:$varToEvaluate ='foo'; [scriptblock]::Create("`$_.$varToEvaluate") 结果:$_.foo
        【解决方案4】:

        最简单的解决方案(需要 V3 或更高版本)如下所示:

        $v1 = "123"
        $v2 = "asdf"
        
        $sb = {
             Write-Host "Values are: $using:v1, $using:v2"
        }
        
        $job = Start-Job -ScriptBlock $sb
        

        您可以认为 $using 大致类似于显式 param() 块并传递 -ArgumentList,只有 PowerShell 会自动为您处理。

        【讨论】:

        • $using 对我来说效果很好。我想知道如何以这种方式传递全局变量。 $using:global:v1 会起作用吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-01
        • 1970-01-01
        • 2023-01-02
        • 1970-01-01
        • 2013-01-17
        • 2019-07-30
        相关资源
        最近更新 更多