PSCustomobject returrning strange output

Hi guys,
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 result for “-count 2”

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

it’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

When you use -count 2 for your Test-Connection you will get 2 results!

Hi Olaf,
i know, how i can make it show only one?

Oooops, sorry … I thought the hint I gave would be enough. :wink:
Either you use -Count 1 or you chose one of the result sets

LocalPC = $test_connection.PSComputerName[0]

If you want the server to run the test-connection twice but only output one responce, you would need to clarify this in the custom object:

    LocalPC = $test_connection.PSComputerName[0]
    Time = $test_connection.ResponseTime[0]
    Bytes = $test_connection.buffersize[0]

This will only show the first results of the test.

The only issue you might have with this is that its only going to show the first attempt, if you want it to show the last attempt change [0] to [1]

You may also want to try removing the pipe to Format-Table – most PSCustomObjects will autoformat in table form anyway, and converting it to text like that can be undesirable and cause funny display things depending on where and when you pipe to the format command.

$PC   = 'mytestPC1'
$Port = 1433

$test_connection = try { # Try/Catch accounts for PC not reachable scenarios
    Test-Connection -ComputerName $PC -Count 2 -EA 1 | select -Last 1 # We're interested in the 2nd ICMP echo
} catch {
    [PScustomObject]@{
        buffersize   = 'Ping Failed'
        ResponseTime = 'Ping Failed'
    }
}

$test_netconnection = Test-NetConnection $PC -Port $Port -WarningAction SilentlyContinue 

[pscustomobject] @{
    LocalPC             = $env:COMPUTERNAME
    'Tested-Server'     = $PC
    Bytes               = $test_connection.buffersize
    Time                = $test_connection.ResponseTime
    RemotePort          = $Port
    TcpTestSucceeded    = $( if ($test_netconnection.TcpTestSucceeded) { $true } else { $false } ) # if statement accounts for Test-NetConnection failure to resolve $PC and failure to ping $PC          
}

Thanks Olaf, i’m familiar with the indexing just didn’t knew that i can implement it like that, actually i didn’t thought about it at all, i think it’s because i don’t have much experiance, but i’m getting it with each script that i write.

Thanks Alex,
is it possible to show two attempts?

is it possible to show two attempts?
?? I thought that's exactly what you wanted to avoid!?

you are right my friend,
I wanted to do that at the beginning because i thought that there is no possible way to do that, i though that it might be something with the test-connection cmdlet

sorry if i explained myself not properly

Hi Sam,
thanks alot for your help, it’s just your answer is to a bit advanced for me yet (i’m still not so good in anderstanding the logic :))
that’s why i asking so much quastion
but you can be sure that i’m looking at that and learning a lot from it

See if this attempt at added notes clears things up for you a bit.

Clear-Host
# The use of the additional parens is just so you see the output of the 
# actions without using the Write-* cmdlets
($PC   = $env:COMPUTERNAME)
($Port = 80)

# capture the test case below and store it in the results in the variable

(
$test_connection = try 
{ 
# using a Try/Catch to determine if host not reachable scenarios
# and get only first two responses, if there is an error Continue anyway

Test-Connection -ComputerName $PC -Count 2 -EA 1 | 
select -Last 1 # We're interested in the 2nd ICMP echo
               # so of the 2 responses, get the last one
} 
catch 
{
# Capture the response info as a custom object

[PScustomObject]@{
buffersize   = 'Ping Failed'
ResponseTime = 'Ping Failed'
}
}
)


# Using the results from the above named variable, use it to test again
# on any error, continue, without displaying the errors

($test_netconnection = Test-NetConnection $PC -Port $Port -WarningAction SilentlyContinue )

# Capture the response info as a custom object
# add a custom parameter for the tested server

[pscustomobject] @{
LocalPC             = $env:COMPUTERNAME
'Tested-Server'     = $PC
Bytes               = $test_connection.buffersize
Time                = $test_connection.ResponseTime
RemotePort          = $Port

# Get the success info of the test as a string

TcpTestSucceeded    = $( if ($test_netconnection.TcpTestSucceeded) 
                        { $true } 
                        else { $false } ) # if statement accounts for 
                                            # Test-NetConnection failure to 
                                            # resolve $PC and failure to ping $PC          
}

# Results

Hi Postanote,
thanks a lot !

Test-Connection -ComputerName $PC -Count 2 -EA 1

is short for

Test-Connection -ComputerName $PC -Count 2 -ErrorAction STOP

See this post for more details.

The -WarningAction parameter in the line

Test-NetConnection $PC -Port $Port -WarningAction SilentlyContinue

Instructs the Test-NetConnection cmdlet to not display the ‘warning’ messages (in dark yellow by default).
These messages do not indicate an error.

‘Warning’ and ‘Error’ are technical terms in this context beyond the basic dictionary definition. Specifically, ‘Warning’ is the third ‘output stream’ and ‘Error’ is the second. Here are the rest:

  • All output
    1 Success output
    2 Errors
    3 Warning messages
    4 Verbose output
    5 Debug messages

For example;

'hi'

is short for

Write-Output -InputObject 'hi'

and it writes to the #1 output stream, aka stdio, aka standard output, aka success output

Write-Error 'this operation failed'

writes to the #2 output stream, aka error output

Errors are saved in the variable $Error
For example, after invoking the last cmdlet above,

$Error[-1] | select *

[-1] selects the last element in the $Error array, that’s the last item written to the ‘error’ stream.
Piping that to ‘select *’ displays all properties like:

writeErrorStream      : True
PSMessageDetails      : 
Exception             : Microsoft.PowerShell.Commands.WriteErrorException: this operation failed
TargetObject          : 
CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
ErrorDetails          : 
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at , : line 1
PipelineIterationInfo : {0, 0, 0}

Objects in the $Error array have the following properties and methods:

$Error[-1] | Get-Member


   TypeName: System.Management.Automation.ErrorRecord

Name                  MemberType     Definition                                                                                                       
----                  ----------     ----------                                                                                                       
Equals                Method         bool Equals(System.Object obj)                                                                                   
GetHashCode           Method         int GetHashCode()                                                                                                
GetObjectData         Method         void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.Streaming...
GetType               Method         type GetType()                                                                                                   
ToString              Method         string ToString()                                                                                                
writeErrorStream      NoteProperty   bool writeErrorStream=True                                                                                       
CategoryInfo          Property       System.Management.Automation.ErrorCategoryInfo CategoryInfo {get;}                                               
ErrorDetails          Property       System.Management.Automation.ErrorDetails ErrorDetails {get;set;}                                                
Exception             Property       System.Exception Exception {get;}                                                                                
FullyQualifiedErrorId Property       string FullyQualifiedErrorId {get;}                                                                              
InvocationInfo        Property       System.Management.Automation.InvocationInfo InvocationInfo {get;}                                                
PipelineIterationInfo Property       System.Collections.ObjectModel.ReadOnlyCollection[int] PipelineIterationInfo {get;}                              
ScriptStackTrace      Property       string ScriptStackTrace {get;}                                                                                   
TargetObject          Property       System.Object TargetObject {get;}                                                                                
PSMessageDetails      ScriptProperty System.Object PSMessageDetails {get=& { Set-StrictMode -Version 1; $this.Exception.InnerException.PSMessageDet...

Hi Sam,
Thanks alot for your explanation.