none
Нарушение сортировки под влиянием Select-Object RRS feed

  • Вопрос

  • Добрый день.

    Скрипт по списку проверяет хосты.

    $HostList = Import-Csv .\Host.csv ForEach ($h in $HostList) { Test-Connection $h.path -count 1 -ErrorAction SilentlyContinue -ErrorVariable ProcessError | Select-Object Address, IPV4Address If ($ProcessError)

    { $text = 'Невозможно соединиться с '+$h.path

    Write-Warning -Message $text} }


    Проблема в том, что если не использовать select, то он формирует нормальную таблицу со всеми графами, а когда доходит до проблемного хоста - выдает warning-message. Но как только я собираюсь отфильтровать - Он в начала списка ставит первый warning с проблемным хостом, потом формирует таблицу с колонками, заполняет её - если где-то встречаются ещё хосты проблемные, то уже вставляет их в таблицу корректно. Почему Select-Object так делает и как это исправить?

    Source Destination IPV4Address IPV6Address Bytes Time(ms)
    ------ ----------- ----------- ----------- ----- --------
    ADMIN1 Server03 10.59.137.43 32       0
    ADMIN1 Server04 10.59.137.44 32       0

    WARNING: Невозможно соединиться с Server05

    WARNING: Невозможно соединиться с Server06

    ADMIN1 Server07 10.59.137.43 37       0

    А так формируется после Select-Object

                                                

    WARNING: Невозможно соединиться с Server05
    Address           IPV4Address  
    -------              -----------  
    Server0110.59.137.41
    Server0210.59.137.42
    Server0310.59.137.43
    Server0410.59.137.44
    WARNING: Невозможно соединиться с Server06
    Server0710.59.137.47

    Первая If($processerror) выпадет за таблицу.





    • Изменено Setteor 10 мая 2017 г. 16:11

Ответы

  • 1 Подозреваю что вы не обнуляете переменную $ProcessError

    2

    $HostList = Import-Csv .\Host.csv ForEach ($h in $HostList)if (Test-Connection $h.path -count 1 -ErrorAction SilentlyContinue) {
    $h | Select-Object Address, IPV4Address
    }
    # End If

    else {
    $text = 'Невозможно соединиться с '+$h.path
    Write-Warning -Message $text
    } # End Else

    } # End Foreach


    The opinion expressed by me is not an official position of Microsoft

    • Помечено в качестве ответа KazunEditor 16 мая 2017 г. 9:05
    Модератор
  • Непонятно, какая конечная цель.
    $HostList = Import-Csv .\Host.csv
    $result = ForEach ($h in $HostList){ 
    	$ip = (Test-Connection $h.path -count 1 -ErrorAction SilentlyContinue).IPV4Address
    	if(!$ip) {$ip = "X"}
    	"" | Select-Object @{n="Address";e={$h.path}}, @{n="IPV4Address";e={$ip}}
    }
    $result



    • Изменено KazunEditor 11 мая 2017 г. 7:24
    • Помечено в качестве ответа KazunEditor 16 мая 2017 г. 9:06
    Отвечающий
  • Добрый день.

    Скрипт по списку проверяет хосты.

    $HostList = Import-Csv .\Host.csv ForEach ($h in $HostList) { Test-Connection $h.path -count 1 -ErrorAction SilentlyContinue -ErrorVariable ProcessError | Select-Object Address, IPV4Address If ($ProcessError)

    { $text = 'Невозможно соединиться с '+$h.path

    Write-Warning -Message $text} }


    Проблема в том, что если не использовать select, то он формирует нормальную таблицу со всеми графами, а когда доходит до проблемного хоста - выдает warning-message. Но как только я собираюсь отфильтровать - Он в начала списка ставит первый warning с проблемным хостом, потом формирует таблицу с колонками, заполняет её - если где-то встречаются ещё хосты проблемные, то уже вставляет их в таблицу корректно. Почему Select-Object так делает и как это исправить?

    Source Destination IPV4Address IPV6Address Bytes Time(ms)
    ------ ----------- ----------- ----------- ----- --------
    ADMIN1 Server03 10.59.137.43 32       0
    ADMIN1 Server04 10.59.137.44 32       0

    WARNING: Невозможно соединиться с Server05

    WARNING: Невозможно соединиться с Server06

    ADMIN1 Server07 10.59.137.43 37       0

    А так формируется после Select-Object

                                                

    WARNING: Невозможно соединиться с Server05
    Address           IPV4Address  
    -------              -----------  
    Server0110.59.137.41
    Server0210.59.137.42
    Server0310.59.137.43
    Server0410.59.137.44
    WARNING: Невозможно соединиться с Server06
    Server0710.59.137.47

    Первая If($processerror) выпадет за таблицу.





    Попробуйте так

    $HostList = Import-Csv .\Host.csv
    $result = @()
    
    ForEach ($h in $HostList){ 
        $result += Test-Connection $h.host -count 1 -ErrorAction SilentlyContinue| Select-Object Address, IPV4Address
        If (!$?){ 
            $text = "Невозможно соединиться с $($h.host)"
            Write-Warning -Message $text
        }
    }
    
    $result 

    ну или

    ForEach ($h in $HostList){ 
        try{
            $result += Test-Connection $h.host -count 1 -ErrorAction Stop | Select-Object Address, IPV4Address
        } 
    
        catch{
            $text = "Невозможно соединиться с $($h.host)"
            Write-Warning -Message $text
        }
    }
    


    • Изменено JabBaton 12 мая 2017 г. 13:29
    • Помечено в качестве ответа KazunEditor 16 мая 2017 г. 9:06

Все ответы

  • 1 Подозреваю что вы не обнуляете переменную $ProcessError

    2

    $HostList = Import-Csv .\Host.csv ForEach ($h in $HostList)if (Test-Connection $h.path -count 1 -ErrorAction SilentlyContinue) {
    $h | Select-Object Address, IPV4Address
    }
    # End If

    else {
    $text = 'Невозможно соединиться с '+$h.path
    Write-Warning -Message $text
    } # End Else

    } # End Foreach


    The opinion expressed by me is not an official position of Microsoft

    • Помечено в качестве ответа KazunEditor 16 мая 2017 г. 9:05
    Модератор
  • Доброго времени суток. Я не профи в пош, и немного не понял Ваши ответы, если позволите, я уточню.

    1. Переменная, как мне кажется обнуляется. Как я понял:

    Сначала я просто через Clear-Variable попробовал, но результат был тот же. Ну, и в отсутствии Select-Object такого нет.

    Далее я попробовал через дебаг прогнать. Потосяно в консоли вызывая $ProcessError - переменная была пуста, до тех пор пока test-connection не смог соединиться. И обнулилась сразу после завершения цикла If.

    [DBG]: PS C:\PS>> $ProcessError
    Test-Connection : Testing connection to computer 'SR13' failed: При просмотре базы данных произошла неисправимая ошибка
    At C:\PS\Проверка соединения по списку.ps1:4 char:6
    +      Test-Connection $H.path -count 1 -ErrorAction SilentlyContinue - ...
    +      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ResourceUnavailable: (SR13:String) [Test-Connection], PingException
        + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
     
    
    [DBG]: PS C:\PS>> 
    WARNING: Невозможно соединиться с SR13
    Hit Line breakpoint on 'C:\PS\Проверка соединения по списку.ps1:4'
    [DBG]: PS C:\PS>> $ProcessError
    Test-Connection : Testing connection to computer 'SR13' failed: При просмотре базы данных произошла неисправимая ошибка
    At C:\PS\Проверка соединения по списку.ps1:4 char:6
    +      Test-Connection $H.path -count 1 -ErrorAction SilentlyContinue - ...
    +      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ResourceUnavailable: (SR13:String) [Test-Connection], PingException
        + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
     
    
    [DBG]: PS C:\PS>> 
    SR14      192.168.2.x
    Hit Line breakpoint on 'C:\PS\Проверка соединения по списку.ps1:5'
    [DBG]: PS C:\PS>> $ProcessError
    
    [DBG]: PS C:\PS>> 
    Hit Line breakpoint on 'C:\PS\Проверка соединения по списку.ps1:4'
    [DBG]: PS C:\PS>> $ProcessError
    
    [DBG]: PS C:\PS>> 

    2. Опять таки, из-за того, что я не гуру PS, возможно я что-то упустил, но предложенный Вами пример не работает. В Цикле If после проверки он просто должен отсортировать переменную $h, которая является вызванными из списка csv значение, а там только имя хоста. Я задумку не уловил. Ну и цикл ForEach не открывается. Можете пояснить?

    Ах, да, забыл добавить. При дебаге такой ошибки не было. То есть он нормально начал.

    Правда цикл Foreach он страно начала, сначла первый вывод test-connectiona пропустил, а при проверке второго хоста вывел оба значения. Но, возможно это глюк ISE.

    • Изменено Setteor 11 мая 2017 г. 7:23
  • Непонятно, какая конечная цель.
    $HostList = Import-Csv .\Host.csv
    $result = ForEach ($h in $HostList){ 
    	$ip = (Test-Connection $h.path -count 1 -ErrorAction SilentlyContinue).IPV4Address
    	if(!$ip) {$ip = "X"}
    	"" | Select-Object @{n="Address";e={$h.path}}, @{n="IPV4Address";e={$ip}}
    }
    $result



    • Изменено KazunEditor 11 мая 2017 г. 7:24
    • Помечено в качестве ответа KazunEditor 16 мая 2017 г. 9:06
    Отвечающий
  • Добрый день.

    Скрипт по списку проверяет хосты.

    $HostList = Import-Csv .\Host.csv ForEach ($h in $HostList) { Test-Connection $h.path -count 1 -ErrorAction SilentlyContinue -ErrorVariable ProcessError | Select-Object Address, IPV4Address If ($ProcessError)

    { $text = 'Невозможно соединиться с '+$h.path

    Write-Warning -Message $text} }


    Проблема в том, что если не использовать select, то он формирует нормальную таблицу со всеми графами, а когда доходит до проблемного хоста - выдает warning-message. Но как только я собираюсь отфильтровать - Он в начала списка ставит первый warning с проблемным хостом, потом формирует таблицу с колонками, заполняет её - если где-то встречаются ещё хосты проблемные, то уже вставляет их в таблицу корректно. Почему Select-Object так делает и как это исправить?

    Source Destination IPV4Address IPV6Address Bytes Time(ms)
    ------ ----------- ----------- ----------- ----- --------
    ADMIN1 Server03 10.59.137.43 32       0
    ADMIN1 Server04 10.59.137.44 32       0

    WARNING: Невозможно соединиться с Server05

    WARNING: Невозможно соединиться с Server06

    ADMIN1 Server07 10.59.137.43 37       0

    А так формируется после Select-Object

                                                

    WARNING: Невозможно соединиться с Server05
    Address           IPV4Address  
    -------              -----------  
    Server0110.59.137.41
    Server0210.59.137.42
    Server0310.59.137.43
    Server0410.59.137.44
    WARNING: Невозможно соединиться с Server06
    Server0710.59.137.47

    Первая If($processerror) выпадет за таблицу.





    Попробуйте так

    $HostList = Import-Csv .\Host.csv
    $result = @()
    
    ForEach ($h in $HostList){ 
        $result += Test-Connection $h.host -count 1 -ErrorAction SilentlyContinue| Select-Object Address, IPV4Address
        If (!$?){ 
            $text = "Невозможно соединиться с $($h.host)"
            Write-Warning -Message $text
        }
    }
    
    $result 

    ну или

    ForEach ($h in $HostList){ 
        try{
            $result += Test-Connection $h.host -count 1 -ErrorAction Stop | Select-Object Address, IPV4Address
        } 
    
        catch{
            $text = "Невозможно соединиться с $($h.host)"
            Write-Warning -Message $text
        }
    }
    


    • Изменено JabBaton 12 мая 2017 г. 13:29
    • Помечено в качестве ответа KazunEditor 16 мая 2017 г. 9:06