Test-NetConnection: A useful PowerShell function for basic network troubleshooting

Author Christian Reading time 2 minutes

Photo by Pixabay: https://www.pexels.com/photo/white-switch-hub-turned-on-159304/

In corporate networks you often encounter technologies likes proxies, SSL Man-in-the-middle (MITM) appliances (to scan HTTPS traffic) and NAT constructs. All can make it hard and cumbersome to troubleshoot certain problems. For example the common: "Why can I successfully connect to this server/service, while my colleague can't?"

This question is usually accompanied by a lack of useful troubleshooting tools like telnet, netcat, nmap and tcpdump/Wireshark. As they are deemed dangerous hacker tools. Luckily there is PowerShell and as I just learned the Test-NetConnection function, which allows us to troubleshoot using basic TCP-Connections - with this knowledge we can at least rule out or identify certain issues.

PS C:\Users\user> Test-NetConnection -ComputerName 192.168.0.1 -Port 443

ComputerName     : 192.168.0.1
RemoteAddress    : 192.168.0.1
RemotePort       : 443
InterfaceAlias   : Ethernet
SourceAddress    : 192.168.0.2
TcpTestSucceeded : True

Or if you prefer it a bit shorter, there is the tnc alias and the -ComputerName argument can be omitted too.

PS C:\Users\user> tnc 192.168.0.1 -Port 443

ComputerName     : 192.168.0.1
RemoteAddress    : 192.168.0.1
RemotePort       : 443
InterfaceAlias   : Ethernet
SourceAddress    : 192.168.0.2
TcpTestSucceeded : True

It's a bit annoying that you have to use the -Port argument. The common notations like IP:Port or IP Port don't work as expected. The reason is that there is a switch-statement in the function which sets the port based on four pre-defined keywords. Sadly not even HTTPS or SSH are in there.

PS C:\Users\user> (Get-Command Test-NetConnection).Definition
[...]
                switch ($CommonTCPPort)
                {
                ""      {$Return.RemotePort = $Port}
                "HTTP"  {$Return.RemotePort = 80}
                "RDP"   {$Return.RemotePort = 3389}
                "SMB"   {$Return.RemotePort = 445}
                "WINRM" {$Return.RemotePort = 5985}
                }
[...]

I don't know if a lookup based on the C:\Windows\System32\drivers\etc\services file is feasible due to Windows file rights, security, etc. But that certainly would be an improvement. Or add some logic like "If the second argument is an integer, use that as the port number".

Anyway, I now have an easy and convenient way of checking TCP-Connections and that is all I need.