31

在powershell中,我想学习将变量调用到启动作业的最佳方法,因此我不必为每个服务器编辑脚本,因为它将根据我放置脚本的客户端而定。

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

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

4

3 回答 3

38

使用-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
于 2012-04-09T16:03:23.473 回答
26

PSv3+ 替代方案补充Keith Hill 的有用答案

$using:范围修饰符可用于引用传递给的脚本块内调用者范围内的变量值,Start-Job作为传递参数的替代方法(默认情况下,作为后台作业执行的脚本块看不到任何调用者的变量或其他定义):

$Servername = 'Server1'
Start-Job { "Target: " + $using:ServerName } | Receive-Job -Wait -AutoRemoveJob

以上产生:

Target: Server1

笔记:

  • 传递脚本块时可以使用相同的技术:

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


[1] 但是,基于线程的并发特性允许间接Start-ThreadJob修改,即如果手头的变量值恰好是(可变).NET引用类型的实例,例如哈希表。请注意,利用这一点可能需要额外的、重要的努力来使并发修改线程安全ForEach-Object Parallel

于 2019-07-31T01:32:25.537 回答
1

其他一些方法,$args 和 $input。这也适用于调用命令,我认为它使用相同的机制。$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。实际上没有 -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
于 2021-10-10T17:16:06.087 回答