PSCustomobject returrning strange output

2019-08-01 13:02发布

问题:

i have a script which is supposed to run a test-connection and a test-netconnection on three servers, for now i'm doing test with "localhost"

the thing is i want the it will make at least two times the "test-connection" and it does, but the output is very strange (from the logical point of view is reasonable, but from the output point of view it's not)

here is the code: if i use the count parameter and set it to 1 time, the output is correct it shows one pc from which it made the test, if i set it to 2 the output is messed up

$computers="localhost"


  foreach ($pc in $computers){

      $test_connection = Test-Connection -ComputerName $pc -Count 2 

      $test_netconnection = Test-NetConnection $pc -Port 1433   

         #}else{ Write-Host "can't reach $pc"}   

        [pscustomobject] @{
                           LocalPC             =$test_connection.PSComputerName
                          'Tested-Server'      =$test_netconnection.ComputerName
                           Bytes               =$test_connection.buffersize
                           Time                =$test_connection.ResponseTime
                           RemotePort          =$test_netconnection.RemotePort
                           TcpTestSucceeded    =$test_netconnection.TcpTestSucceeded

                           }| ft -AutoSize #end of Customobject
                           }                                                                                                          
                           #}#end of foreach loop    
pause

the output:

WARNING: TCP connect to (::1 : 1433) failed
WARNING: TCP connect to (127.0.0.1 : 1433) failed

LocalPC            Tested-Server Bytes    Time   RemotePort TcpTestSucceeded
-------            ------------- -----    ----   ---------- ----------------
{LEVL-01, LEVL-01} localhost     {32, 32} {0, 0}       1433            False

t's also showing strange output in the second that i'm adding the Erroraction parameter (but i'll leave it for another post) how can i make these double "local-pc" output transfer into one?

thanks alot for your help

回答1:

Per the comments, your issue is that $test_connection ends up containing two objects, one for each test result. You can select the result of a specific object by either using the array index operator e.g [0] or you could use Select -First 1 to get the first result. I recommend the latter because you're less likely to get an exception thrown if the result happens to be empty.

As a further suggestion, you could return the average result of the time taken to do both tests, by using Measure-Object -Average. I also suggest that you don't use Format-Table within your loop, but instead collate the results in to a variable and then use it on that variable at the end.

Here are those revisions in your code:

$computers="localhost"

$Result = foreach ($pc in $computers){

    $test_connection = Test-Connection -ComputerName $pc -Count 2
    $test_netconnection = Test-NetConnection $pc -Port 1433   

    [pscustomobject] @{
        LocalPC          = ($test_connection | Select -First 1).PSComputerName
        'Tested-Server'  = $test_netconnection.ComputerName
        Bytes            = ($test_connection | Select -First 1).Bytes
        Time             = ($test_connection | Measure-Object -Average ResponseTime).Average
        RemotePort       = $test_netconnection.RemotePort
        TcpTestSucceeded = $test_netconnection.TcpTestSucceeded
    }
}                                                                                                          

$Result | Ft -AutoSize


回答2:

This will create a separate object for each 'ping' attempt:

$computers="localhost"

foreach ($pc in $computers)
{
    $test_netconnection = Test-NetConnection $pc -Port 1433

    Test-Connection -ComputerName $pc -Count 2 |
        ForEach-Object {
            [pscustomobject] @{
                                LocalPC             =$_.PSComputerName
                                'Tested-Server'     =$test_netconnection.ComputerName
                                Bytes               =$_.buffersize
                                Time                =$_.ResponseTime
                                RemotePort          =$test_netconnection.RemotePort
                                TcpTestSucceeded    =$test_netconnection.TcpTestSucceeded

                                }
        } | ft -AutoSize #end of Customobject  
}