Understanding (advanced) Foreach-Object

by Apr 7, 2018

Hi guys, i'm new here.

I'm new to powershell (learning it only two months or something like that) and this is my 4th script

which is started in a very basic way, of two commands

1)test-connection

2)test-netconnection

After reading and asking a lot of questions , some people told me that my script have to much text and i can simplify it by using a PSCustomobject, what ended as a new problem, because i had problems with the  output, so i asked more question, and finally got a solution that will do what my first script does (almost)

here is the first version of the script 

$computers= "localhost"

foreach ($pc in $computers){

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

$test_netconnection = Test-NetConnection $pc -Port 1433

[pscustomobject] @{
       LocalPC                     =$test_connection.PSComputerName;
       'now testing server: '  =$test_netconnection.ComputerName
       Bytes                          =$test_connection.buffersize
       Time                           =$test_connection.ResponseTime
       RemotePort                =$test_netconnection.RemotePort

}|ft -AutoSize
}

here is the output for this (if i set the "test-connection" count parameter to 1, i'm not getting this result):

LocalPC now testing server: Bytes Time RemotePort
——- ——————- —– —- ———-
{LEVL-01, LEVL-01} localhost {32, 32} {0, 0} 1433

i didn't knew how to make it show only one line even if i use two tests of test-connection, i understand that powershell store it in Arrey, but i didn't knew what can i do with that, untill this one guy in some forum writed this script:

$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

}

i didn't knew that you use foreach-object like that, until now i've seen on youtube and CBT and some other instructions, a use of that in a some lines that looks
something like that get-blahblah |foreach-object {blabhalbha}.

can some one explain me what he did here? he used this "$_" sign (i understand what it mean – foreach-object that pass through the pipeline) but how can it be that it's not showing the result as double.

PS: during the writing of the post, i've started to wonder, how can i add "if statement" to this kind of a script where do i add it? inside the pipeline? because if there is some connectivity problem i don't want the script to stop on one server, i need to make it check all the servers to know on which of them there is problem 

Thanks a lot for your help.