PowerShell:在特定节点上启动特定 Tasks/Processes

PowerShell: Start Specific Tasks/Processes on Specific Nodes

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

在每个 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 是一个不同的范围,它不会传递声明的值吗?

看起来问题出在 $a 变量的范围上。脚本块内的 $a 变量与在其外部定义的 $a 不同,因此在脚本块 运行s 之后,您的 $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