gpt4 book ai didi

powershell - 使用 Powershell 在远程服务器上分发脚本级作业

转载 作者:行者123 更新时间:2023-12-04 15:09:14 25 4
gpt4 key购买 nike

更多的理论问题...

我有一个存在于三台服务器上的 powershell 脚本。在这个例子中,三个服务器是:

  • 服务器1
  • 服务器2
  • server3

  • 我正在使用另一台机器, server4 , 调用脚本 C:\ExampleScript.ps1 远程使用 调用命令 通过 指定远程机器时计算机名 范围。该脚本的最终目的是检测powershell是否正在运行,如果没有,则计算机“不忙”,可以打开被远程调用的脚本。如果计算机“忙碌”,请移至下一个服务器并继续通过三台机器,直到所有参数值都用完为止。如果所有机器都忙,最好有办法定期检查进程并查看它们是否仍然打开。通过这种方式,脚本的执行可以在各种机器之间以一种原始的方式进行平衡。

    考虑以下代码:
    $servers = "server1","server2","server3"
    $data = "param1", "param2", "param3", "param4", "param5", "param6"

    #somehow loop through the different servers/data using the above arrays
    $job = Invoke-Command $servers[0] {
    $ProcessActive = Get-Process powershell -ErrorAction SilentlyContinue
    if($ProcessActive -eq $null)
    {
    "Running"
    Invoke-Command -ComputerName $env:computername -FilePath C:\ExampleScript.ps1 -ArgumentList $data[0]
    }
    else
    {
    "Busy go to next machine"
    }
    } -AsJob
    Wait-Job $job
    $r = Receive-Job $job
    $r

    试图实现的预期结果是尝试根据是否存在事件的 powershell 进程在机器之间对脚本进行负载平衡,如果没有,则移动到下一台机器并执行相同的测试和后续可能的执行。该脚本应该遍历 $data 数组(或其他)中指定的所有值。

    最佳答案

    我发现这个问题很有趣,所以我想试一试。

    $servers = "server1","server2","server3"

    $data = New-Object System.Collections.ArrayList
    $data.AddRange(@("param1", "param2", "param3", "param4", "param5", "param6"))

    $jobs = New-Object System.Collections.ArrayList

    do
    {
    Write-Host "Checking job states." -ForegroundColor Yellow
    $toremove = @()
    foreach ($job in $jobs)
    {
    if ($job.State -ne "Running")
    {
    $result = Receive-Job $job

    if ($result -ne "ScriptRan")
    {
    Write-Host " Adding data back to que >> $($job.InData)" -ForegroundColor Green
    $data.Add($job.InData) | Out-Null
    }

    $toremove += $job
    }
    }

    Write-Host "Removing completed/failed jobs" -ForegroundColor Yellow
    foreach ($job in $toremove)
    {
    Write-Host " Removing job >> $($job.Location)" -ForegroundColor Green
    $jobs.Remove($job) | Out-Null
    }

    # Check if there is room to start another job
    if ($jobs.Count -lt $servers.Count -and $data.Count -gt 0)
    {
    Write-Host "Checking servers if they can start a new job." -ForegroundColor Yellow
    foreach ($server in $servers)
    {

    $job = $jobs | ? Location -eq $server
    if ($job -eq $null)
    {
    Write-Host " Adding job for $server >> $($data[0])" -ForegroundColor Green
    # No active job was found for the server, so add new job
    $job = Invoke-Command $server -ScriptBlock {
    param($data, $hostname)
    $ProcessActive = Get-Process powershell -ErrorAction SilentlyContinue
    if($ProcessActive -eq $null)
    {
    # This will block the thread on the server, so the JobState will not change till it's done or fails.
    Invoke-Command -ComputerName $hostname -FilePath C:\ExampleScript.ps1 -ArgumentList $data
    Write-Output "ScriptRan"
    }
    } -ArgumentList $data[0], $env:computername -AsJob
    $job | Add-Member -MemberType NoteProperty -Name InData -Value $data[0]
    $jobs.Add($job) | Out-Null
    $data.Remove($data[0])
    }
    }
    }
    # Just a manual check of $jobs
    Write-Output $jobs
    # Wait a bit before checking again
    Start-Sleep -Seconds 10
    } while ($data.Count -gt 0)

    基本上,我创建了一个数组,并不断为每个服务器填充一个作业。

    新作业开始时,数据从列表中删除,如果作业失败,则重新添加。这是为了避免服务器使用相同的数据/参数运行脚本。

    我目前缺乏一个合适的环境来正确测试这个,但明天会在工作中试一试,并在需要时用任何更改更新我的答案。

    关于powershell - 使用 Powershell 在远程服务器上分发脚本级作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36482009/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com