使用PowerShell将变量传递给Start-Job

39

我希望学习在PowerShell中如何最好地调用变量来启动任务,这样我就不必针对每个服务器编辑脚本,因为它将根据我放置脚本的客户端而具体指定。

$Servername = 'Server1'
    $pingblock = {
      pathping $servername | Out-File C:\client\PS\ServerPing.TXT
    }
    start-job $pingblock

当我运行上面的代码时,我只得到一个帮助文件,就像我忘记指定$servername一样。

3个回答

51
为了补充Keith Hill的有益答案,提供一个PSv3+替代方案
可以使用$using:作用域修饰符来引用调用者作用域内变量的值,在传递参数的替代方案中,(默认情况下,作为后台工作执行的脚本块不会看到调用者的任何变量或其他定义)。
$Servername = 'Server1'
Start-Job { "Target: " + $using:ServerName } | Receive-Job -Wait -AutoRemoveJob

上述内容产生了:
Target: Server1

注意:
  • 同样的技巧也可以用于:

  • 请注意,与-ArgumentList (-Args)一样,只传递变量,而不是变量本身;也就是说,您不能修改调用者的变量。[1]


[1] 但是,基于线程的并发特性 - Start-ThreadJobForEach-Object Parallel - 允许间接修改,即如果手头的变量值恰好是一个(可变的).NET引用类型的实例,如哈希表,在这种情况下,指向该变量的对象可以被修改(如果它是可变的)。请注意,利用这一点需要额外的、不容易的努力来使并发修改线程安全,例如使用并发(同步)集合 - 参见这个答案 - 和/或显式锁定单个对象 - 参见这个答案


45

使用 -ArgumentList 参数在 Start-Job 上,例如:

Start-Job -Scriptblock {param($p) "`$p is $p"} -Arg 'Server1'

根据您的情况:

$pingblock = {param($servername) pathping $servername | Out-File C:\...\ServerPing.txt}
Start-Job $pingblock -Arg Server1

3

还有其他几种方式,$args 和 $input。invoke-command 也是同样的机制。$input 方法在处理数组时有些出乎意料。

start-job { $args[0] } -args hi | receive-job -wait -auto
hi


echo hi | start-job { $input } | receive-job -wait -auto
hi


echo hi there | start-job { $input.gettype() } | receive-job -wait -auto

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
False    False    <GetReadEnumerator>d__20                 System.Object

对于数组,最好使用foreach-object (%)循环,以便在并行处理每个数组项。另请参见PowerShell 7中的start-threadjob或foreach-object -parallel。实际上,start-job没有-throttlelimit选项,因此要谨慎使用。

echo yahoo.com facebook.com |
   % { $_ | start-job { test-netconnection $input } } |
   receive-job -wait -auto | select * -exclude runspaceid,pssourcejob* | ft

ComputerName RemoteAddress ResolvedAddresses PingSucce
                                             eded
------------ ------------- ----------------- ---------
yahoo.com    74.6.143.25   {74.6.143.25,...} True
facebook.com 31.13.71.36   {31.13.71.36}     True

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接