2012-03-06 19 views
1

我有一个aprox 1000行脚本,它循环遍历AD中的所有服务器。 脚本ping每个服务器并执行一堆WMI查询如果ping = ok。 我的脚本将结果存储在散列表中,我在脚本结尾输出为CSV。 这个工程,但它是sloooow ..我们正在谈论接近两个小时。我一直在考虑这样做更有效率,我认为-asjob听起来像个好主意。通过-asjob使脚本​​更高效

但我能做到这一点作为并行工作吗?我的服务器会处理负载吗?并且正在采取这种做法吗?

盼望某些输入,而我在等我的脚本来运行它的周期..

编辑

我的看法是,脚本等待测试连接(平)返回true或错误。我想同时运行多个ping。

EDIT 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 
} 

注: 我在脚本 结束输出$服务器列表到CSV文件我列出aprox的500台服务器我完整的脚本。

+0

首先,你需要确定哪些部分是缓慢的,然后发布那些在你的问题,所以我们可以提出改进建议。 – 2012-03-06 13:39:25

+0

如果您在循环的每次迭代中使用'Test-Connection',并且如果这是最慢的事情,您需要重新处理逻辑以同时运行ping测试,因为您首先需要服务器列表,您可以同时测试与它们的连接。你不必一次做所有的服务器,你一次可以说10-20。 – 2012-03-06 18:10:02

+0

谢谢安迪!是否有可能将我在服务器列表中的所有foreach重写为开始工作?或者那会不那么聪明? :) – Sune 2012-03-06 19:17:07

回答

3

我会建议编写一个处理所有服务器验证(ping,WMI等)的函数,然后将其包装在Start-Job命令中。为了避免你的服务器资源超载,我建议在你的任务中包装某种“工作管理器”。

foreach ($Server in $ServerList) { 
    while ((Get-Job -State Running).Count -ge 20) { 
     Start-Sleep -Seconds 5; 
    } 
    # Start-Job here 
} 
+0

谢谢Trevor!那么你的代码片段不会做超过20个并发作业?这听起来很聪明。但是,我如何跟踪返回的内容? – Sune 2012-03-07 08:31:50

+0

Hello Sune,您将使用Receive-Job cmdlet来接收每个作业的结果。你可以在完成之后,在foreach循环中(或者更好的是,在while循环中,(哈哈)等待其他工作完成时),或者在foreach循环之后,当所有作业完成时执行此操作。 – 2012-03-07 15:40:27

1

您是否考虑过仅在您的第一个wmi请求失败时执行ping操作?如果故障很少发生,那么这应该切这块工作量出来的图片”的

为什么WMI请求失败的平将作为排除故障的第一步。

我会踢了多种结合本兼职。

到底是如何你ping命令?您可以共享的代码?有可能是优化那里。

+0

嗨Marceljg!我已经添加了我的代码:) – Sune 2012-03-07 11:03:40

+0

我没有看到任何明显的改进建议对测试连接本身。 – marceljg 2012-03-07 13:59:50

+0

如何将整个scriptblock作为一项工作? – Sune 2012-03-07 14:49:47

0

测试连接和ping总是要慢,我有一个类似的脚本。得到所有域中的服务器,并从每个proc util,ram util,disk fr收集统计数据ee,所有的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 

}