2012-03-06 4 views
1

У меня есть примерный скрипт 1000 aprox, который проходит через все серверы в AD. Скрипт связывает каждый сервер и выполняет кучу WMI-запросов, если ping = ok. Мой скрипт хранит результаты в хэш-таблице, которую я выводил в CSV в конце скрипта. Это работает, но это sloooow .. Мы говорим около двух часов. Я занимаюсь этим более эффективным, и я думаю, что-азбука звучит как хорошая идея.Создание сценария более эффективно с -asjob

Но могу ли я сделать это как совместные задания? Будет ли мой сервер обрабатывать нагрузку? А есть способ сделать это?

Надеясь на входе в то время как я жду моего сценария для запуска это цикл ..

EDIT

Мое мнение таково, что сценарий ждет тест-соединения (пинг), чтобы вернуть истинный или false. Я хотел бы запускать несколько пинов одновременно.

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 
} 

Примечания: Я вывод $ SERVERLIST в CSV-файл в конце сценария я список APROX 500 серверов в полный сценарий.

+0

Прежде всего, необходимо определить, какие части медленно, а затем разместить те в вашем вопросе, чтобы мы могли предложить улучшения. –

+0

Если вы используете 'Test-Connection' на каждой итерации цикла, и если это самая медленная вещь, вам нужно будет немного переработать логику для запуска тестов ping одновременно, потому что вам сначала нужен список серверов, тогда вы можете одновременно тестировать соединения с ними. Вам не нужно делать все серверы одновременно, вы можете сказать, что 10-20 за раз. –

+0

Спасибо Энди! Можно ли переделать весь мой foreach в списке серверов на начальную работу? Или это было бы не так умно? :) – Sune

ответ

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

Спасибо, Тревор! Таким образом, ваш фрагмент не выполняет более 20 параллельных заданий? Это звучит умно. Но как мне отслеживать, что возвращается? – Sune

+0

Здравствуйте, Sune, вы должны использовать командлет Receive-Job для получения результатов каждого задания. Вы можете сделать это по завершении, внутри цикла foreach (или, еще лучше, в цикле while, в то время как (haha) вы ожидаете завершения других заданий) или после цикла foreach, когда все задания завершены. –

1

Рассматривали ли вы ping только при отказе от первого запроса wmi? Если отказы редки, то это должно сократить эту часть нагрузки из картины»

пинг будет служить в качестве первого шага в устранении неполадок, почему запрос WMI не удалось.

Я бы совместить это с сбрасывая множественным параллельные задания.

Как именно вы пинг? можете ли вы поделиться этим куском кода? там могут быть оптимизации там.

+0

Привет, Марсельдж! Я добавил свой код :) – Sune

+0

Я не вижу каких-либо явных улучшений, чтобы предложить самому тестовому соединению. – marceljg

+0

Как сделать весь скриптовый блок как работу? – Sune

0

теста подключением и пинг всегда медленно, у меня есть подобный сценарий. получают все серверы в домене и собирает статистические данные от каждого, proc util, ram util, disk fr ee, все nic stats и т. д.

Я нашел функцию тестового порта, не помню, где я ее нашел, но тест порта составляет всего лишь 0,3 секунды, затем я запускаю тестовое соединение, если оно выполнено успешно.

Для всех серверов тестирование порта 135, для тестового порта питания постоянного тока 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 

}

Смежные вопросы