Windows Server has had PowerShell versions of the classic network tools since 2012 R2. They return objects instead of text, so you can filter the output and use it in scripts. All of them come with Windows and work in Windows PowerShell 5.1 and in PowerShell 7 on Windows, but not in PowerShell on Linux or macOS. The Linux equivalents are in Test whether a TCP port is reachable and Find which process is listening on a port.
Test a TCP port
Test-NetConnection opens a TCP connection to the port and closes it again. It replaces telnet host 443, and you don’t need the Telnet client installed.
PS> Test-NetConnection web1.example.com -Port 443 ComputerName : web1.example.comRemoteAddress : 192.0.2.80RemotePort : 443InterfaceAlias : EthernetSourceAddress : 192.0.2.15TcpTestSucceeded : True
When the test fails, a warning names the address and port, and TcpTestSucceeded is False. The output can also include a ping result. A failed ping on its own doesn’t mean the host is down, since many servers and firewalls drop ICMP: read TcpTestSucceeded, which answers the question you asked.
PS> Test-NetConnection web1.example.com -Port 5432WARNING: TCP connect to (192.0.2.80 : 5432) failed# trimmed: the address and ping linesTcpTestSucceeded : False
| Option | What it does |
|---|---|
-InformationLevel Quiet | Returns only True or False, for scripts |
-CommonTCPPort RDP | Tests a well-known port by name: HTTP, RDP, SMB, or WINRM |
-TraceRoute -Hops 15 | Lists the routers on the way, like tracert |
-InformationLevel Detailed | Adds the name resolution results and the route the test used |
PS> if (-not (Test-NetConnection db1.example.com -Port 5432 -InformationLevel Quiet)) { Write-Error 'db1 is unreachable on 5432' }PS> Test-Connection db1.example.com -TcpPort 5432
Test-Connection -TcpPort is the PowerShell 7 way to ask the same question, and it also works on Linux and macOS. Neither command can test UDP: a UDP port doesn’t answer unless the service on it replies to what you send.
Look up DNS records
Resolve-DnsName replaces nslookup. By default it asks the resolvers the server is configured with, in the same order as Windows does for every other program.
PS> Resolve-DnsName example.com -Type MX Name Type TTL Section NameExchange Preference---- ---- --- ------- ------------ ----------example.com MX 3600 Answer mail.example.com 10 PS> Resolve-DnsName example.com -Type TXT -Server 1.1.1.1PS> Resolve-DnsName 192.0.2.10
| Option | What it does |
|---|---|
-Type | The record type: A, AAAA, CNAME, MX, TXT, NS, SOA, SRV, PTR |
-Server 1.1.1.1 | Asks that server instead of the configured ones, to compare what different resolvers return |
-DnsOnly | Uses DNS only, without falling back to LLMNR or NetBIOS on the local network |
-NoHostsFile | Ignores entries in C:\Windows\System32\drivers\etc\hosts |
-CacheOnly | Answers from the local DNS cache, without sending a query |
Given an address, as in the last line above, it looks up the PTR record. After a record changes, clear the local cache so the next lookup asks again:
PS> Get-DnsClientCache -Entry web1.example.comPS> Clear-DnsClientCache
Clear-DnsClientCache does the same as ipconfig /flushdns. It clears this server’s cache only. The resolver it asks keeps its own copy until the record’s TTL runs out.
Find which process listens on a port
PS> Get-NetTCPConnection -State Listen -LocalPort 5432 | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object { Get-Process -Id $_ | Select-Object Id, ProcessName, Path } Id ProcessName Path -- ----------- ----3184 postgres C:\Program Files\PostgreSQL\16\bin\postgres.exe
Get-NetTCPConnection replaces netstat -ano, which still works. A port with nothing listening on it returns an error rather than an empty result, so add -ErrorAction SilentlyContinue in scripts. For UDP, use Get-NetUDPEndpoint -LocalPort 53.
PS> Get-NetTCPConnection -State Listen -LocalPort 443 LocalAddress LocalPort RemoteAddress RemotePort State AppliedSetting OwningProcess------------ --------- ------------- ---------- ----- -------------- -------------:: 443 :: 0 Listen 40.0.0.0 443 0.0.0.0 0 Listen 4
Process 4 is System. It means the port belongs to HTTP.sys, the kernel’s HTTP server, which IIS, WinRM, and other programs register addresses with. netsh http show servicestate view=requestq lists the registered addresses and the process IDs behind them. For a process called svchost, find the service inside it:
PS> Get-CimInstance Win32_Service -Filter "ProcessId = 1240" | Select-Object Name, DisplayNameShow addresses, gateway, and DNS servers
PS> Get-NetIPConfiguration InterfaceAlias : EthernetInterfaceIndex : 6InterfaceDescription : Microsoft Hyper-V Network AdapterIPv4Address : 192.0.2.15IPv4DefaultGateway : 192.0.2.1DNSServer : 192.0.2.53# trimmed: the profile and IPv6 lines PS> Get-NetIPAddress -AddressFamily IPv4 | Format-Table InterfaceAlias, IPAddress, PrefixLength, PrefixOrigin
The DNS servers listed here are the ones Resolve-DnsName and every other program ask. A wrong entry there explains a name that resolves on one server and not on the next.
Check the firewall for a port
A service can listen and still be unreachable because no inbound rule allows the port. This lists the enabled inbound rules for TCP 443. It reads every port filter first, so it takes a few seconds on a server with hundreds of rules.
PS> Get-NetFirewallPortFilter | Where-Object { $_.Protocol -eq 'TCP' -and $_.LocalPort -contains '443' } | Get-NetFirewallRule | Where-Object { $_.Enabled -eq 'True' -and $_.Direction -eq 'Inbound' } | Format-Table DisplayName, Profile, Action DisplayName Profile Action----------- ------- ------World Wide Web Services (HTTPS Traffic-In) Any Allow
The filter matches rules that name port 443 on its own. A rule for a range such as 443-445 or for any port doesn’t show up. To allow the port:
PS> New-NetFirewallRule -DisplayName 'HTTPS in' -Direction Inbound -Protocol TCP -LocalPort 443 -Action AllowLast checked on 24 October 2026 against Windows Server 2019, Windows Server 2022, Windows Server 2025, Windows PowerShell 5.1, and PowerShell 7.4. If a step doesn’t match what you see, contact us with the command and what it printed.