The cmdlet,
Test-Connection
does provide a mechanism for this use case.
Test-Connection -Source 'SomeIPA' -Destination 'SomeDest'
Native ping in any OS provides this as well via the source switch.
You can get InterfaceIndex using
Get-Netadapter
cmdlet in recent versions of PowerShell. ---
Get-NetAdapter -Physical | Where Status -eq 'up'
--- below v3, you'd do ---
netsh interface ipv4 show interfaces
--- or ---
Get-WmiObject -Class win32_networkadapter
Any connectivity test will only occur with a nic that has connectivity and is properly routed. There are several articles and Q&A's that talk to your use case. A quick web search will show them to you. 'ping using a specific nic'
Examples:
Ping from specific network adapter on Windows
The adapter chosen is based on the routing tables. You can examine the
routing tables by running 'route print' or 'netstat -r'. Each entry
will have a metric which dictates the weighting of the route - lower
numbers are preferred. You can manipulate the routing table with the
'route' command. route /? for details.
route add (destination subnet) MASK (destination subnet mask)
(gateway) IF (interface)
Probably easier is to use the -S switch, which lets you specify the
source IP address (see ping /? for more infos).
Another thing you can do is change the binding order, which meets your
"option to prefer one adapter over the other". Although it varies from
Windows OS to OS, it is in a similar location as this example: For
Windows 7 you right click on Network, and click properties. Then you
click on ""Change adapter settings". Then click on the menu
Advanced>Advanced Settings and move the connection you want to have
priority to the top.
From Windows 7 (Version 6.1 Build 7601: Service Pack 1) ping /? Usage:
ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
[-r count] [-s count] [[-j host-list] | [-k host-list]]
[-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name
Ping using specific gateway interface or source IP address
Ping using specific source IP address One can set socket stuff. The
syntax is:
ping -S ip dest
ping -S 192.168.2.24 www.cyberciti.biz
ping -c 4 -S 10.207.0.54 1.1.1.1
Can I try to ping a website through a specific adapter?
OK, missed the Port thing, but, Test-NetConnection is not in legacy PowerShell period, so not an option, and it does not provide a source switch either anyway.
(Get-Command Test-Connection).Parameters.Keys
AsJob
DcomAuthentication
WsmanAuthentication
Protocol
BufferSize
ComputerName
Count
Credential
Source
Impersonation
ThrottleLimit
TimeToLive
Delay
Quiet
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
(Get-Command Test-NetConnection).Parameters.Keys
ComputerName
TraceRoute
Hops
CommonTCPPort
Port
DiagnoseRouting
ConstrainSourceAddress
ConstrainInterface
InformationLevel
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
You could take the route of using the .Net libraries. Which is how it's been documented in legacy PowerShell. Using stuff like ...
--- New-Object Net.Sockets.TcpClient ---
$tcpObj = New-Object Net.Sockets.TcpClient
$tcpObj.Connect($Ipaddress,$Port)
More info on that namespace is here:
https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient?view=netframework-4.8
... combining the results from ping or Test-Connection and piping that to Net.Sockets to deal with the port check.
For example (since this was sort of interesting I threw this together and tested it - so I know it works - well not on W2K3 as I've had none of those in over a decade.):
Clear-Host
$SourceIpa = 'SomeSourceNicIpa'
$TargetDestination = 'Stackoverflow.com'
$TargetResponseCount = 1
$DestinationPort = 443
try
{
$DestinationIpa = (Test-Connection -Source $SourceIpa -ComputerName $TargetDestination -Count $TargetResponseCount).ipv4address.ipaddressToString
$tcpObj = New-Object Net.Sockets.TcpClient($DestinationIpa,$DestinationPort)
if($tcpObj -ne $null)
{
"Using the source $SourceIpa. The port $DestinationPort on destination $TargetDestination is open."
$tcpObj.close()
}
}
catch
{
Write-Warning -Message "Using the source $SourceIpa. The port $DestinationPort on destination $TargetDestination is not open."
$tcpObj.close()
}
And a similar approach could have been done with ping and the .Net namespace as well.