首页 > 解决方案 > PowerShell:在特定节点上启动特定任务/进程

问题描述

我有一个进程会根据用户请求的 CPU 数量在文件共享上创建代理文件夹。例如,如果用户请求两台服务器(这是在 AWS 中完成的),每台服务器都有 2 个 CPU,我的进程将在文件共享上创建 4 个代理文件夹,即代理 1、代理 2、代理 3、代理 4。

在每个 Agent 文件夹中都有一个 .exe 文件,我们称之为 test.exe。我需要做的是让每个代理文件夹根据 CPU 计数运行。因此,在此示例中,Agent1 和 Agent2 将在 server1 上运行,Agent3 和 Agent4 将在 server2 上运行。

这是我当前的代码:

        $NodeArray = @('server1','server2')
        $a = 1
        $Node = 2 (Calculation done to divide the total amount of CPUs by the # of servers requested)
        
        Foreach ($server in $NodeArray) {             

         (Runs Invoke command to create PSSession then runs Invoke to map the share locally)

              $ScriptBlock = { param ($MasterNode, $ControlFile, $Node, $a)
              do {
                 $Arguments = "$ControlFile /H ${MasterNode}:4004"
                 Start-Process -FilePath "test.exe" -WorkingDirectory "C:\Test\Agent$a" -ArgumentList $Arguments
                 Start-Sleep -Seconds 10
                 $a++
              } Until ($a -gt $Node)
                                
              $Node = $Node + $Node
        }
    }

这是可行的,但是它先在服务器 1 上启动 Agent1,然后在服务器 2 上启动,然后移动到 Agent2 并在服务器 1 上启动它,然后在服务器 2 上启动它,依此类推,直到 Agent4 中断循环。

如前所述,预期的行为应该是服务器 1 上的 Agent1 和 Agent2,然后迭代和循环并在服务器 2 上启动 Agent3 和 Agent4。

感谢您提供的任何帮助!

编辑:

$NodeArray = @('172.22.218.100', '172.22.150.140')
$NumServer = 2
$CPU = 2
$Global:CPUTotal = [int]$CPU * 2
$Node = [int]$CPUTotal / [int]$NumServer
$a = 1
write-host "A 1: $a"
write-host "Node 1: $node"
   
    Foreach ($server in $NodeArray) {

        write-host "A 2: $a"
        write-host "Node 2: $node"
        
        $ScriptBlock = {
            param ($computer, $Node, $a)

            write-host "A 3: $a"
            write-host "Node 3: $node"
            
            do {
                Write-Host server: $computer `t Max Agent: $Node `t Agent: $a
                write-host "A 4: $a"
                write-host "Node 4: $node"
                $a++
            } Until ($a -gt $Node)

            write-host "A 5: $a"
            write-host "Node 5: $node"

            }

        Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $server, $a, $Node

        $a = $Node + 1

        $Node = $Node + $Node

    }

当我运行上面的代码时,我收到这个输出:

A 1: 1
Node 1: 2
A 2: 1
Node 2: 2
A 3: 2
Node 3: 1
server: 172.22.218.100   Max Agent: 1    Agent: 2
A 4: 2
Node 4: 1
A 5: 3
Node 5: 1
A 2: 3
Node 2: 4
A 3: 4
Node 3: 3
server: 172.22.150.140   Max Agent: 3    Agent: 4
A 4: 4
Node 4: 3
A 5: 5
Node 5: 3

我正在做一个写主机,$Node你可以看到第一个和第二个等于 2,这是正确的,但是当它进入它的那一刻,它将$Scriptblock它设置为 1。我得到了相同的行为$a(尽管数量不同)。您提到的$Scriptblock是不同的范围,它不会像声明的那样传递值吗?

标签: windowspowershellloopsserver

解决方案


看起来问题在于您的 $a 变量的范围。脚本块内的 $a 变量与它外部定义的 $a 不同,因此在脚本块运行后,您的 $a 变量仍将设置为 1,并且您的下一个服务器将再次从 agent1 开始。您需要在每次运行后重新定义 $a 变量。

    $NodeArray = @('server1', 'server2')
    $a = 1
    $Node = 2       # (Calculation done to divide the total amount of CPUs by the # of servers requested)
    
    Foreach ($server in $NodeArray) {
    
        #  (Runs Invoke command to create PSSession then runs Invoke to map the share locally)
    
        $ScriptBlock = {
            param($computer, $Node, $a)
            do {
                Write-Host server: $computer `t Max Agent: $Node `t Agent: $a
                $a++
            } until ($a -gt $Node)
        }
    
    
        Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $server, $Node, $a
    
        # $a is still equal to 1 here since $a in scriptblock has a different scope
    
        # set $a to next Agent
        $a = $Node + 1
    
        $Node = $Node + $Node
    }
server: server1          Max Agent: 2    Agent: 1
server: server1          Max Agent: 2    Agent: 2
server: server2          Max Agent: 4    Agent: 3
server: server2          Max Agent: 4    Agent: 4

推荐阅读