Powershell - 如何为 Start-Job 预先评估脚本块中的变量

Posted

技术标签:

【中文标题】Powershell - 如何为 Start-Job 预先评估脚本块中的变量【英文标题】:Powershell - how to pre-evaluate variables in a scriptblock for 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 的空值。我怎样才能让它们在脚本块中评估(传递给),然后再传递给后台作业?

【问题讨论】:

【参考方案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 会起作用吗?

以上是关于Powershell - 如何为 Start-Job 预先评估脚本块中的变量的主要内容,如果未能解决你的问题,请参考以下文章

如何为asp.net 4.0编写IIS预热脚本?

如何为格式列表输出添加前缀?

从 C# PowerShell cmdlet 返回退出代码

powershell核心错误:未加载指定的模块'RPC-Client'

AWS EC2多账户的Powershell脚本

使用PowerShell 批量Enable OneDrive for business