更多的理论问题......
我有一个存在于三台服务器上的powershell脚本.在此示例中,三个服务器是:
我正在使用另一台机器server4,使用Invoke-Command远程调用脚本C:\ ExampleScript.ps1,同时通过ComputerName参数指定远程机器.该脚本的最终目标是检测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
Run Code Online (Sandbox Code Playgroud)
试图实现的预期结果是尝试基于是否存在活动的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)
Run Code Online (Sandbox Code Playgroud)
基本上我创建一个数组,并为每个服务器保持不断填充一个作业.
新作业启动时,数据将从列表中删除,如果作业失败,则会将其添加回来.这是为了避免服务器运行具有相同数据/参数的脚本.
我目前缺乏适当的环境来测试这个问题,但是明天会在工作中给它一个旋转,如果需要的话,可以在任何更改时更新我的答案.
| 归档时间: |
|
| 查看次数: |
234 次 |
| 最近记录: |