Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

powershell - Variables in Start-Job do not get evaluated

My Powershell code doesn't evaluate the $agent variable:

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

This link is similar to my problem, except I'm not calling an external Powershell script.

I tried adding that in, using $args[0] for $agent, and adding the -ArgumentList parameters, but that didn't work.


Edits/Replies

$agentcomputers is just a list of computer names - each on its own line:

$agentcomputers = Get-Content c:grinder-distagent-computers.txt

I have also tried this - and $args[0] doesn't evaluate:

Start-Job -ScriptBlock {& psexec $args[0] c:grinderexamplesstartAgent.cmd} -ArgumentList @($agent)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here are 3 different ways I would do it. First, all aligned and pretty.

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

Or you could just put it all on one line without creating any variables.

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

And in this final example, you could manage how many threads are run concurrently by doing it this way.

$MaxThreads = 5
$agents = Get-Content c:grinder-distagent-computers.txt
$jobs = {
     Param($agent)
         write-host "Starting agent on" $agent
         & psexec \$agent c:grinderexamplesstartAgent.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
} 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...