我有一个aprox 1000行脚本,它遍历AD中的所有服务器。 如果ping = ok,脚本会ping每个服务器并执行一堆WMI查询。 我的脚本将结果存储在哈希表中,我在脚本末尾输出到CSV。 这是有效的,但它是sloooow ..我们正在谈论接近两个小时。我一直在考虑这样做更有效率,我认为-asjob听起来是个好主意。
但我可以将此作为并发作业吗?我的服务器会处理负载吗?是-asjob的方式呢?
在等待我的脚本运行循环时,希望得到一些输入。
修改
我的观点是脚本等待测试连接(ping)返回true或false。我想同时运行多个ping。
编辑2
(注意: 我已经开始一个单独的问题,因为我觉得我的原始问题已得到解答。无论如何,我已经包含了我当前的代码。感谢大家投球! new question here! )
到目前为止,感谢大家的帮助!我被要求列出我的代码,以提供我想要做的实际例子。
这是我的代码中的一个小而有效的摘录:
# 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
}
$serverlistlist += $serverinfo | Select-Object SystemName,IPAddress,OSName
}
注意: 我将$ serverlist输出到脚本末尾的csv文件中 我在完整的脚本中列出了aprox 500服务器。
答案 0 :(得分:3)
我建议编写一个处理所有服务器验证的函数(ping,WMI等),然后将其包装在Start-Job命令中。为了避免服务器资源过载,我建议围绕你的任务包装某种“工作经理”。
foreach ($Server in $ServerList) {
while ((Get-Job -State Running).Count -ge 20) {
Start-Sleep -Seconds 5;
}
# Start-Job here
}
答案 1 :(得分:1)
您是否考虑过仅在第一次wmi请求失败时才进行ping操作?如果失败很少,那么这应该从图片“
中删除这一部分工作量ping将作为解决wmi请求失败原因的第一步。
我会将此与开始多个并发作业相结合。
你究竟在打什么?你能分享那段代码吗?那里也可能有优化。
答案 2 :(得分:0)
测试连接和ping总是慢,我有一个类似的脚本。获取域中的所有服务器,并从每个服务器收集统计数据,proc util,ram util,disk free,所有nic统计数据等
我发现了一个测试端口功能,无法记住我发现它的位置,但端口测试只有大约0.3秒,如果成功,我会运行测试连接。
对于所有服务器测试端口135,对于dc的测试端口389
function Verify_SinglePort{ ## returns True or false - avoids local host
Param ($CPUNAME, $port)
# This works no matter in which form we get $host - host name or ip address
If($ScriptMachineFQDN -eq $CPUNAME){
## not a good idea to test a port to and from the same machine
return $true
}
try {
$ip = [System.Net.Dns]::GetHostAddresses($CPUNAME) | select-object IPAddressToString -expandproperty IPAddressToString
if($ip.GetType().Name -eq "Object[]")
{
#If we have several ip's for that address, let's take first one
$ip = $ip[0]
}
} catch {
#Write-Host "Possibly $CPUNAME is wrong host name or IP"
return $false
}
$t = New-Object Net.Sockets.TcpClient
# We use Try\Catch to remove exception info from console if we can't connect
try
{
$t.Connect($ip,$port)
} catch {}
if($t.Connected)
{
$t.Close()
$msg = "Port $port is operational"
return $true
}
else
{
$msg = "Port $port on $ip is closed, "
$msg += "You may need to contact your IT team to open it. "
return $false
}
#Write-Host $msg
}