Same Job, Different Shell Part 11: The Complete Cheat Sheet
Ten parts, ten task categories, one recurring shape: Linux and Windows both have a fast legacy text tool and a more structured modern one, and the two platforms didn’t converge on the same tool boundaries when they built them. This closing part is just the reference, every pair from Parts 1 through 10 in one table, meant to be the page you actually bookmark rather than any single part.
The full reference
| Task | Linux | Windows |
|---|---|---|
| Basic reachability test | ping -c 4 <host> | Test-Connection -ComputerName <host> -Count 4 |
| Continuous ping | ping <host> | ping -t <host> (PS 7+ only: Test-Connection -ComputerName <host> -Repeat) |
| Boolean up/down for scripts | ping -c 1 -W 1 <host> (exit code) | Test-Connection -ComputerName <host> -Count 1 -Quiet |
| Path trace | traceroute <host> | tracert <host> |
| Path trace as structured data | n/a (parse text) | Test-NetConnection -ComputerName <host> -TraceRoute |
| TCP-mode trace (through ICMP/UDP-blocking firewalls) | traceroute -T -p <port> <host> | no built-in equivalent |
| Live continuous trace+ping | mtr <host> | no built-in equivalent |
| Interface summary | ip -brief addr show | ipconfig |
| Full interface detail | ip addr show | ipconfig /all |
| IPv4 addresses only, structured | ip -4 addr show | Get-NetIPAddress -AddressFamily IPv4 |
| Adapter/link state | ip -brief link show | Get-NetAdapter |
| Assign an address | ip addr add <cidr> dev <if> | New-NetIPAddress -InterfaceAlias <if> -IPAddress <ip> -PrefixLength <n> |
| Full routing table | ip route show | route print |
| Routing table, structured | ip route show (parse) | Get-NetRoute |
| Which route a destination takes | ip route get <ip> | Get-NetRoute -DestinationPrefix <ip>/32 (approximate) |
| Add a route | ip route add <cidr> via <gw> | New-NetRoute -DestinationPrefix <cidr> -InterfaceAlias <if> -NextHop <gw> |
| DNS lookup, script-friendly | dig +short <name> | Resolve-DnsName -Name <name> |
| DNS lookup, quick/manual | nslookup <name> | nslookup <name> |
| Query a specific record type | dig <name> MX | Resolve-DnsName -Name <name> -Type MX |
| Query a specific DNS server | dig <name> @<server> | Resolve-DnsName -Name <name> -Server <server> |
| View local DNS cache | resolvectl query <name> (if systemd-resolved is running) | ipconfig /displaydns |
| Flush local DNS cache | resolvectl flush-caches | ipconfig /flushdns |
| Listening ports + owning process | ss -tulpn | Get-NetTCPConnection -State Listen joined to Get-Process |
| Established connections only | ss -tan state established | Get-NetTCPConnection -State Established |
| Legacy connections tool | netstat -tulpn (needs net-tools) | netstat -ano |
| Full ARP/neighbor table | ip neigh show | Get-NetNeighbor |
| Legacy ARP tool | arp -a | arp -a |
| Only confirmed-reachable neighbors | ip neigh show nud reachable | Get-NetNeighbor -State Reachable |
| Clear the neighbor/ARP cache | ip neigh flush all | arp -d * (or Get-NetNeighbor | Remove-NetNeighbor -Confirm:$false) |
| Basic TCP port check | nc -zv <host> <port> | Test-NetConnection -ComputerName <host> -Port <port> |
| Port check with no nc installed | (echo > /dev/tcp/<host>/<port>) && echo open | n/a, always available |
| Well-known service port shortcut | manual port number | Test-NetConnection -ComputerName <host> -CommonTCPPort SMB|RDP|HTTP|WINRM |
| Is the firewall even on | ufw status | netsh advfirewall show allprofiles state |
| Full firewall ruleset | iptables -L -n -v | Get-NetFirewallRule -PolicyStore ActiveStore |
| Only enabled inbound rules | iptables -L INPUT -n -v | Get-NetFirewallRule -Enabled True -Direction Inbound |
| Start a packet capture | tcpdump -i <if> -w out.pcap '<filter>' | pktmon start --capture --comp nics |
| Capture only dropped packets | not natively supported | pktmon start --drop-only |
| Convert to a Wireshark-readable file | native (.pcap) | pktmon etl2pcap <file>.etl --out <file>.pcapng |
PowerShell: which cmdlets actually change behavior between versions
This came up enough times across the series that it’s worth its own table rather than nine separate footnotes. Windows ships two PowerShell editions side by side — 5.1 Desktop (the inbox default) and 7+ Core (a separate install, pwsh) — and only one thing tested across this whole series actually behaves differently between them.
Core PowerShell cmdlets — version matters:
Test-Connection (Part 1) is the one confirmed case, tested side by side on 5.1 and 7.6.3 against the same target. It was rewritten essentially from scratch for PowerShell 7, and the two versions don’t just differ in flags: 5.1 has no -Repeat/-Continuous/-TimeoutSeconds at all, and in one tested run 5.1’s reported address for a literal-IP ping didn’t match what was actually asked for, where 7.6.3’s did. -ComputerName is the one parameter confirmed to work identically on both; -TargetName and the continuous-ping flags are 7+ only.
Windows-only module cmdlets (NetTCPIP, NetAdapter, NetSecurity, DnsClient) — version-consistent in everything this series tested:
Test-NetConnection -TraceRoute (Part 2) is the one directly confirmed side by side on both 5.1 and 7.6.3, identical fields and behavior. Get-NetIPAddress/Get-NetAdapter (Part 3), Get-NetRoute/New-NetRoute (Part 4), Resolve-DnsName (Part 5), Get-NetTCPConnection (Part 6), Get-NetNeighbor/Remove-NetNeighbor (Part 7), Test-NetConnection -Port (Part 8), and Get-NetFirewallRule (Part 9) were each run for real, but only on one PowerShell version at a time rather than head to head like Parts 1 and 2 — so this is stated as “same module family as the confirmed-consistent cases, and nothing in this series turned up a difference,” not as independently re-verified for every cmdlet. These cmdlets live in Windows-only CIM/binary modules rather than PowerShell’s cross-platform core, so they weren’t part of the 7+ rewrite that split Test-Connection in two, which is the mechanical reason to expect the consistency in the first place.
The practical rule: if a cmdlet’s noun starts with Net (Get-NetRoute, Get-NetAdapter, Get-NetFirewallRule, and so on) or is Test-NetConnection, treat it as version-portable. If it’s a bare cross-platform verb-noun with no Net in it — Test-Connection is the only one in this series — check $PSVersionTable before you trust a flag exists on whatever PowerShell happens to be installed on the box in front of you.
The pattern, if there is one
Looking back across all ten parts, the actual shape isn’t “Windows has fewer tools” or “Linux is more powerful”, it’s that the two ecosystems drew the line between “quick text tool” and “structured tool” in different places. Linux’s ip, ss, and dig are already the modern, structured answer to most of these questions, and the legacy tools (ifconfig, netstat, route) sit alongside them mostly for muscle memory and older scripts. Windows kept ping, tracert, ipconfig, netstat, and arp as the fast, always-present layer, and built a completely separate, genuinely well-designed cmdlet layer (Test-NetConnection, Get-NetTCPConnection, Get-NetRoute, Get-NetNeighbor, Get-NetIPAddress) on top for anything you actually want to script against.
The practical upshot: if you’re troubleshooting live on a box, either platform’s legacy layer gets you an answer fast. If you’re writing something that has to run unattended, parse output, or make a decision, reach for ip/ss/dig on Linux and the Get-Net*/Test-* cmdlets on Windows, both were built for exactly that, and neither platform’s older tools were.
The full series:
- Reachability and Continuous Monitoring
- Path Tracing
- Interface and IP Configuration
- Routing Tables
- DNS Lookups and Resolution
- Active Connections and Sockets
- ARP and Neighbor Tables
- Port and Service Testing
- Firewall Status, Read-Only
- Packet Capture
- The Complete Cheat Sheet (this post)