【问题标题】:Variables in Start-Job do not get evaluatedStart-Job 中的变量不会被评估
【发布时间】:2012-04-17 18:01:01
【问题描述】:

我的 Powershell 代码不计算 $agent 变量:

foreach ($agent in $agentcomputers) {
    Write-Output 'Starting agent on '$agent
    # psexc to start the agent
    Start-Job -ScriptBlock {& psexec $agent c:\grinder\examples\startAgent.cmd}
}

This link 与我的问题类似,只是我没有调用外部 Powershell 脚本。

我尝试将其添加进去,使用$agent 使用$args[0],并添加-ArgumentList 参数,但这不起作用。


编辑/回复

$agentcomputers 只是计算机名称的列表 - 每个都在自己的行中:

$agentcomputers = Get-Content c:\grinder-dist\agent-computers.txt

我也试过这个 - $args[0] 没有评估:

Start-Job -ScriptBlock {& psexec $args[0] c:\grinder\examples\startAgent.cmd} -ArgumentList @($agent)

【问题讨论】:

  • 您需要通过 $args 数组或参数块来使用 ArgumentList 参数。
  • 你也可以改变你的 $agent 变量的范围,我认为:$global:agent.
  • @DavidBrabant 全局范围不起作用,因为它是在单独的 PowerShell.exe 进程中执行的。数据被序列化并传递给后台进程。
  • 你如何确定 $agent 没有被评估?如果您使用测试写入输出 $agent 更改 psexec 您是否有相同的行为?没有错误输出?
  • 您可能需要根据 psexec 的 documentation "\\$args[0]" 使用反斜杠。确保该命令在没有后台作业的情况下自行运行。

标签: powershell


【解决方案1】:

这里有 3 种不同的方法。 首先,所有对齐和漂亮。

$agents = Get-Content c:\grinder-dist\agent-computers.txt
$jobs = {
     Param($agent)
         write-host "Starting agent on" $agent
         & psexec \\$agent c:\grinder\examples\startAgent.cmd
}
foreach($agent in $agents) {
     Start-Job -ScriptBlock $jobs -argumentlist $agent | Out-Null
}
Get-Job | Wait-Job | Receive-Job

或者您可以将所有内容放在一行而不创建任何变量。

(Get-Content c:\grinder-dist\agent-computers.txt) | %{ Start-Job -ScriptBlock { param($_) write-host "Starting agent on" $_; & psexec \\$_ c:\grinder\examples\startAgent.cmd } -argumentlist $_ | Out-Null }
Get-Job | Wait-Job | Receive-Job

在最后一个示例中,您可以通过这种方式管理并发运行的线程数。

$MaxThreads = 5
$agents = Get-Content c:\grinder-dist\agent-computers.txt
$jobs = {
     Param($agent)
         write-host "Starting agent on" $agent
         & psexec \\$agent c:\grinder\examples\startAgent.cmd
}
foreach($agent in $agents) {
     Start-Job -ScriptBlock $jobs -argumentlist $agent | Out-Null
     While($(Get-Job -State 'Running').Count -ge $MaxThreads) {
          sleep 10
     }
     Get-Job | Wait-Job | Receive-Job
} 

【讨论】:

    【解决方案2】:

    这里是解决方案。正如安迪所说,我需要使用带有 -ArgumentList 参数的 $args 数组。这个其他线程很有帮助:Powershell: passing parameters to a job

    foreach($agent in $agentcomputers){
    $agentslash = "\\"+$agent
    $args = ($agentslash,"c:\grinder\examples\startAgent.cmd")
    Write-Output 'Starting agent on '$agent
    
    #psexc to start the agent
    $ScriptBlock = {& 'psexec' @args } 
    
    Start-Job -ScriptBlock $ScriptBlock -ArgumentList $args
    
    }
    

    【讨论】:

      猜你喜欢
      • 2013-11-19
      • 2020-01-13
      • 2011-04-25
      • 1970-01-01
      • 2023-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多