start-job Выполнить команду параллельно и вывести результат по мере их поступления

Я пытаюсь получить конкретное существование KBXXXXXX в списке серверов, но как только мой скрипт один сервер, он требует времени и возвращает результат и возвращается, а затем переходит к следующему. этот скрипт прекрасно работает для меня. Я хочу, чтобы мой скрипт запускался и получал исправления в качестве задания и другого процесса, просто чтобы собрать результаты и отобразить их.

$servers = gc .\list.txt 
foreach ($server in $servers) 
{ 
    $isPatched = (Get-HotFix -ComputerName $server | where HotFixID -eq 'KBxxxxxxx') -ne $null 
    If ($isPatched) 
    { 
    write-host $server + "Exist">> .\patchlist.txt} 
    Else  
    { 
    Write-host $server +"Missing"
$server  >> C:\output.txt
    } 

}

Цель состоит в том, чтобы список выполнялся быстрее, чем последовательно.

3 ответа

В Powershell V2 вы можете использовать задания, как в ответе @Andy, а также более подробно в этой ссылке. Может ли Powershell запускать команды параллельно?

В PowerShell V2 вы также можете проверить этот сценарий http://gallery.technet.microsoft.com/scriptcenter/Foreach-Parallel-Parallel-a8f3d22b с использованием пространств выполнения

С PowerShell V3 у вас есть foreach -parallel вариант.

например (NB Measure-Command просто есть время, чтобы вы могли сделать сравнение)

Workflow Test-My-WF {  
  param([string[]]$servers)

  foreach -parallel ($server in $servers) {

    $isPatched = (Get-HotFix -ComputerName $server | where {$_.HotFixID -eq 'KB9s82018'}) -ne $null     
    If ($isPatched) 
    { 
        $server | Out-File -FilePath "c:\temp\_patchlist.txt" -Append
    } 
    Else  
    { 
        $server | Out-File -FilePath "c:\temp\_output.txt" -Append 
    } 
  }
}

Measure-Command -Expression { Test-My-WF   $servers }

Вместо использования заданий используйте возможность запроса нескольких компьютеров, встроенных в командлет. Многие командлеты Microsoft, особенно те, которые используются для управления системой, принимают массив строк в качестве входных данных для -Computername параметр. Передайте список серверов, и командлет запросит их все. Большинство командлетов, которые имеют эту возможность, будут запрашивать серверы последовательно, но Invoke-Command будем делать это параллельно.

Я не проверял это, поскольку у меня нет загруженной Windows в данный момент, но это должно помочь вам начать (по порядку).

$servers = gc .\list.txt 
$patchedServers = Get-HotFix -ComputerName $servers | where HotFixID -eq 'KBxxxxxxx'|select machinename

$unpatchedServers = compare-object -referenceobject $patchedServers -differenceobject $servers -PassThru

$unpatchedServers |out-file c:\missing.txt;
$patchedServers|out-file c:\patched.txt;

В параллели:

$servers = gc .\list.txt 
$patchedServers = invoke-command -computername $servers -scriptblock {Get-HotFix | where HotFixID -eq 'KBxxxxxxx'}|select -expandproperty pscomputername |sort -unique

Как и прежде, у меня нет подходящей версии Windows, доступной на данный момент, чтобы протестировать вышеизложенное и проверить вывод, но это отправная точка.

Для этого используйте задания PowerShell.

командлеты:

  • Найти работу
  • Receive-Job
  • Remove-Job
  • Start-Job
  • Stop-Job
  • Wait-Job

Вот непроверенный пример:

$check_hotfix = {
    param ($server)
    $is_patched = (Get-HotFix -ID 'KBxxxxxxx' -ComputerName $server) -ne $null 
    if ($is_patched) { 
        Write-Output ($server + " Exist") 
    } else { 
        Write-Output ($server + " Missing")
    }
}

foreach ($server in $servers) {
    Start-Job -ScriptBlock $check_hotfix -ArgumentList $server | Out-Null
}

Get-Job | Wait-Job | Receive-Job | Set-Content patchlist.txt
Другие вопросы по тегам