Windows PowerShell, and an old-school command line tool favorite, collided today when I brainlessly typed the following:
PS C:\> ping computer1,computer2 Bad parameter computer2
This didn’t work, and as quickly as I realized my mistake, I thought, I’m going to have to fix it so ping can accept multiple computers.
There’s a couple ways I can do this, but my idea was to create an advanced function to do the work. I did that, but before I share the function, we should discuss what we could have done. We could have simply made an alias named ping that would run the Test-Connection cmdlet, a cmdlet that can handle a comma-separated list of computer names. Here’s an example of creating the alias and then using it to ping multiple computers.
PS C:\> New-Alias -Name ping -Value Test-Connection PS C:\> ping computer1,computer2 Source Destination IPV4Address IPV6Address Bytes Time(ms) ------ ----------- ----------- ----------- ----- -------- TOMMYMS PC... computer1 10.10.10.30 32 1 TOMMYMS PC... computer2 10.10.10.31 32 1 TOMMYMS PC... computer1 10.10.10.30 32 1 TOMMYMS PC... computer2 10.10.10.31 32 1 TOMMYMS PC... computer1 10.10.10.30 32 1 TOMMYMS PC... computer2 10.10.10.31 32 1 TOMMYMS PC... computer1 10.10.10.30 32 2 TOMMYMS PC... computer2 10.10.10.31 32 2
The reason this works is because of command precedence. If an alias and a command line tool share the same name, the alias will always run when the name is entered.
Well, this wasn’t quite want I wanted. I thought instead, I would make a wrapper around Test-Connection, called Test-TMConnection that would include a switch parameter (-Ping) that would return the standard ping results. I’ll dump in the function below and then we can walk though what it does.
Function Test-TMConnection { [CmdletBinding()] Param ( [Parameter(Mandatory=$true)] [string[]]$ComputerName, [switch]$Ping ) Begin { } # End Begin Process { If ($Ping) { ForEach ($Computer in $ComputerName) { ping $Computer } } Else { Test-Connection -ComputerName $ComputerName } } # End Process } # End Function
Here’s how this works: The function is called by entering Test-TMConnection, the -ComputerName parameter, and then either one computer name, or a comma-separated list of computers. If the -Ping parameter is not used, it will run the standard Test-Connection cmdlet against the computer(s), like we saw in the alias example above. If -Ping is included, it will loop though the computers, using each one with ping. Here’s an example that includes the -Ping parameter.
PS C:\> Test-TMConnection -ComputerName computer1,computer2 -Ping Pinging computer1.mydomain.com [10.10.10.30] with 32 bytes of data: Reply from 10.10.10.30: bytes=32 time=2ms TTL=121 Reply from 10.10.10.30: bytes=32 time=1ms TTL=121 Reply from 10.10.10.30: bytes=32 time=1ms TTL=121 Reply from 10.10.10.30: bytes=32 time=1ms TTL=121 Ping statistics for 10.10.10.30: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 1ms, Maximum = 2ms, Average = 1ms Pinging computer2.mydomain.com [10.10.10.31] with 32 bytes of data: Reply from 10.10.10.31: bytes=32 time=1ms TTL=121 Reply from 10.10.10.31: bytes=32 time=2ms TTL=121 Reply from 10.10.10.31: bytes=32 time=1ms TTL=121 Reply from 10.10.10.31: bytes=32 time=1ms TTL=121 Ping statistics for 10.10.10.31: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 1ms, Maximum = 2ms, Average = 1ms
Important: Keep in mind, that if you were to use something like this, that you’ll be giving up other parameters that are included with ping and Test-Connection. This includes -t with ping, and -Count, and -Source with Test-Connection. In the end, the ping alias might be the better option.