2015-01-06 7 views
1

Я пишу функцию для сбора информации WMI с разных компьютеров. первое, что я делаю, это проверить, могу ли я получить доступ к текущему компьютеру, а если нет, то пишу-ошибку и продолжить. Мой вопрос: как я могу записать ошибки на экран , а затем результаты успешных звонков? (сокращенный код :)Ошибки перед записью в PowerShell

Function Get-Info 
{ 
    Param([Parameter(ValueFromPipeline=$true)] 
    [string[]] $computerName = ".") 
    Process 
    { 
     foreach ($Computer in $ComputerName) 
     { 
      if (-Not $(test-connection $computer -Count 2 -ErrorAction SilentlyContinue)) 
      { 
       Write-Error "Unable to access $computer" 
       continue 
      } 
      $Info = get-WMIObject -Class <someClass> -ComputerName $Computer 
      $result = New-Object PSObject -Property @{ 
       Prop1 = $Info.Property 
       <# ... #> } 
      Write-Output $Result 
     } 
    } 
} 

Когда я запрашиваю коллекцию систем, я получаю info, <error>, info, <error> и не <error>,<error>,info... чего я хочу.

Любая помощь была бы принята с благодарностью.

+0

Чтобы уточнить: вы хотите, чтобы все ошибки печатались до всех успешных результатов? – arco444

+1

Не могли бы вы захватить результаты в массиве '$ results + = $ result' вне цикла foreach' Write-Output $ Results'? – Matt

+1

Обратите внимание, что 'Write-Error' и' Write-Output' записываются в разные потоки. Сообщения печатаются последовательно для любого отдельного потока, но нет гарантированного порядка в разных потоках. –

ответ

0

Просто накапливают свои результаты в переменной, то вывод, что после того, как он закончил, и все ошибки записываются:

$Result = $computers | Get-Info 
$Result 
0

Здесь вы идете, я просто собрал все ошибки в $ errorComputers, и все успешных компьютеров в $ validComputers, а затем отобразить их в конце кода. Обратите внимание, что подход не очень хорошо использует конвейер PowerShell (вообще!), Но он достигает цели, которую вы ищете, перечисляя ошибки до действительных записей.

Function Get-Info 
{ 
Param([Parameter(ValueFromPipeline=$true)] 
[string[]] $computerName = ".") 
Process 
{ 
    foreach ($Computer in $ComputerName) 
    { 
     if (-Not $(test-connection $computer -Count 2 -ErrorAction SilentlyContinue)) 
     { 
      $errorcomputers += $computer 
      continue 
     } 
     $Info = get-WMIObject -Class <someClass> -ComputerName $Computer 
     $result = New-Object PSObject -Property @{ 
      Prop1 = $Info.Property 
      <# ... #> } 
     $validComputers += $Result 
    } 
} 
$errorcomputers | ForEach-Object { 
    Write-Warning "Unable to contact $PSitem" 
    } 
$validComputers 
} 

Теперь, в этом втором примере, я использовал Try/Catch вместо вашей предыдущей логики. Это должно гарантировать, что ваши ошибки будут отображаться первыми, и будет поддерживать функцию блока процесса для скорости.

Function Get-Info 
{ 
Param([Parameter(ValueFromPipeline=$true)] 
[string[]] $computerName = ".") 
Process 
{ 
    foreach ($Computer in $ComputerName) 
    { 

    try {test-connection $computer -Count 1 -ErrorAction Stop} 
    catch{Write-Error "Unable to access $computer" 
       Continue} 
     $Info = get-WMIObject -Class <someClass> -ComputerName $Computer 
     $result = New-Object PSObject -Property @{ 
      Prop1 = $Info.Property 
      <# ... #> } 
     Write-Output $Result 
    } 
    } 
} 
+0

Привет всем, спасибо за ввод. Я думаю, что нет отличного способа сделать то, что я хочу сделать. Как отметил 1RedOne, я хочу использовать хорошую практику для конвейера, и я бы предпочел не собирать объекты и вместо этого использовать write-output для каждого отдельного объекта (хорошее использование конвейера). – GLaisne

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