Sun*_*une 4 powershell foreach jobs
大家好!
我一直在寻找一种方法来提高我的脚本效率,我得出结论(在StackOverflow上的好人帮助下),Start-Job是要走的路.
我有以下foreach-loop,我想在$ servers中的所有服务器上同时运行.我在理解如何实际收集从Receive-Job返回的信息并添加到$ serverlist时遇到问题.
PS:我知道我远远没有把这个钉死,但我真的很感激一些帮助开始,因为我对Start-Job和Receive-Job如何工作感到非常难过.
# List 4 servers (for testing)
$servers = Get-QADComputer -sizelimit 4 -WarningAction SilentlyContinue -OSName *server*,*hyper*
# Create list
$serverlistlist = @()
# Loop servers
foreach($server in $servers) {
# Fetch IP
$ipaddress = [System.Net.Dns]::GetHostAddresses($Server.name)| select-object IPAddressToString -expandproperty IPAddressToString
# Gather OSName through WMI
$OSName = (Get-WmiObject Win32_OperatingSystem -ComputerName $server.name ).caption
# Ping the server
if (Test-Connection -ComputerName $server.name -count 1 -Quiet ) {
$reachable = "Yes"
}
# Save info about server
$serverInfo = New-Object -TypeName PSObject -Property @{
SystemName = ($server.name).ToLower()
IPAddress = $IPAddress
OSName = $OSName
}
$serverlist += $serverinfo | Select-Object SystemName,IPAddress,OSName
}
Run Code Online (Sandbox Code Playgroud)
笔记
And*_*ndi 11
由于您的循环只需要使用字符串,因此很容易将其转换为并发脚本.
下面是一个使循环使用后台作业来加速处理的示例.
代码将循环遍历数组并启动后台作业以运行脚本块中的代码$sb.该$maxJobs变量控制一次运行的作业数,该$chunkSize变量控制每个后台作业将处理的服务器数.
在脚本块中添加其余处理,添加要返回到PsObject的任何其他属性.
$sb = {
$serverInfos = @()
$args | % {
$IPAddress = [Net.Dns]::GetHostAddresses($_) | select -expand IPAddressToString
# More processing here...
$serverInfos += New-Object -TypeName PsObject -Property @{ IPAddress = $IPAddress }
}
return $serverInfos
}
[string[]] $servers = Get-QADComputer -sizelimit 500 -WarningAction SilentlyContinue -OSName *server*,*hyper* | Select -Expand Name
$maxJobs = 10 # Max concurrent running jobs.
$chunkSize = 5 # Number of servers to process in a job.
$jobs = @()
# Process server list.
for ($i = 0 ; $i -le $servers.Count ; $i+=($chunkSize)) {
if ($servers.Count - $i -le $chunkSize)
{ $c = $servers.Count - $i } else { $c = $chunkSize }
$c-- # Array is 0 indexed.
# Spin up job.
$jobs += Start-Job -ScriptBlock $sb -ArgumentList ( $servers[($i)..($i+$c)] )
$running = @($jobs | ? {$_.State -eq 'Running'})
# Throttle jobs.
while ($running.Count -ge $maxJobs) {
$finished = Wait-Job -Job $jobs -Any
$running = @($jobs | ? {$_.State -eq 'Running'})
}
}
# Wait for remaining.
Wait-Job -Job $jobs > $null
$jobs | Receive-Job | Select IPAddress
Run Code Online (Sandbox Code Playgroud)
以下是每个作业处理单个服务器的版本:
$servers = Get-QADComputer -WarningAction SilentlyContinue -OSName *server*,*hyper*
# Create list
$serverlist = @()
$sb = {
param ([string] $ServerName)
try {
# Fetch IP
$ipaddress = [System.Net.Dns]::GetHostAddresses($ServerName)| select-object IPAddressToString -expandproperty IPAddressToString
# Gather OSName through WMI
$OSName = (Get-WmiObject Win32_OperatingSystem -ComputerName $ServerName ).caption
# Ping the server
if (Test-Connection -ComputerName $ServerName -count 1 -Quiet ) {
$reachable = "Yes"
}
# Save info about server
$serverInfo = New-Object -TypeName PSObject -Property @{
SystemName = ($ServerName).ToLower()
IPAddress = $IPAddress
OSName = $OSName
}
return $serverInfo
} catch {
throw 'Failed to process server named {0}. The error was "{1}".' -f $ServerName, $_
}
}
# Loop servers
$max = 5
$jobs = @()
foreach($server in $servers) {
$jobs += Start-Job -ScriptBlock $sb -ArgumentList $server.Name
$running = @($jobs | ? {$_.State -eq 'Running'})
# Throttle jobs.
while ($running.Count -ge $max) {
$finished = Wait-Job -Job $jobs -Any
$running = @($jobs | ? {$_.State -eq 'Running'})
}
}
# Wait for remaining.
Wait-Job -Job $jobs > $null
# Check for failed jobs.
$failed = @($jobs | ? {$_.State -eq 'Failed'})
if ($failed.Count -gt 0) {
$failed | % {
$_.ChildJobs[0].JobStateInfo.Reason.Message
}
}
# Collect job data.
$jobs | % {
$serverlist += $_ | Receive-Job | Select-Object SystemName,IPAddress,OSName
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12683 次 |
| 最近记录: |