Introduction
When troubleshooting network latency, packet loss, or routing issues, network administrators have historically reached for the traditional command-line utility tracert. While this legacy tool gets the job done, modern IT environments require more robust, programmable solutions. In an era dominated by automation, cloud infrastructure, and configuration-as-code, raw text outputs from CMD can create severe debugging bottlenecks.
Performing a powershell traceroute completely transforms your diagnostic workflow. Instead of flat text, PowerShell handles data as structured .NET objects. When you execute a trace route powershell style, the output is highly queryable, allowing you to instantly filter, sort, and export path analytics to formats like CSV or JSON, or stream alerts to your monitoring stack. Whether you are validating local connections, investigating public endpoints, or debugging cloud firewalls, this guide covers everything you need to run, optimize, and automate traceroutes natively in PowerShell.
Tracert vs. PowerShell Traceroute: Understanding the Shift
Under the hood, any traceroute operation relies on the Internet Control Message Protocol (ICMP) and the Time-To-Live (TTL) field of IP packets to map network topology. The tracing machine sends a series of packets to the destination, starting with a TTL of 1. The first router along the path decrements the TTL to 0, drops the packet, and returns an ICMP Type 11 "Time Exceeded" message. The sender records this router's IP and latency, then increments the TTL to 2, mapping the next router. This process repeats until the packet reaches the target destination.
While the underlying network protocol behaves identically across different terminals, the way you interact with the results is fundamentally different. Here is how legacy CMD utilities compare to modern PowerShell cmdlets:
| Feature | Legacy tracert.exe (CMD) | Test-NetConnection (Windows PowerShell 5.1) | Test-Connection (PowerShell 7+ Core) |
|---|---|---|---|
| Output Format | Unstructured Plain Text (String) | Structured .NET Object | Structured .NET Object |
| Real-Time Streaming | Yes | No (Wait for complete execution) | Yes (Streams hops in real-time) |
| Platform Compatibility | Windows Only | Windows Only | Cross-Platform (Windows, macOS, Linux) |
| DNS Resolution Control | Yes (-d flag disables DNS lookup) |
No (Always resolves DNS) | Yes (Omit -ResolveDestination to skip) |
| Scripting Integration | Poor (Requires complex regex parsing) | Excellent (Native object properties) | Excellent (Direct pipeline support) |
For ad-hoc, manual checks on a local workstation, running the old tracert utility is fine. However, when writing an automation script, building dynamic reports, or verifying connectivity on non-Windows endpoints, using native traceroute in powershell cmdlets is the superior choice.
Running a Native Traceroute in Windows PowerShell 5.1
For systems running standard Windows 10, Windows 11, or Windows Server, Windows PowerShell 5.1 is the default shell. In this classic environment, the primary diagnostic cmdlet is Test-NetConnection. Introduced in PowerShell 4.0, this cmdlet was designed to consolidate ping, traceroute, and port validation into a single command.
To execute a basic windows powershell traceroute to a target like google.com, use the following command:
Test-NetConnection -ComputerName google.com -TraceRoute
To save time, you can also use the built-in alias tnc:
tnc google.com -TraceRoute
Deconstructing the Output
Unlike classic command-line utilities, Test-NetConnection will run the entire diagnostic trace before returning a clean, structured object to your terminal:
ComputerName : google.com
RemoteAddress : 142.250.190.46
InterfaceAlias : Wi-Fi
SourceAddress : 192.168.1.15
PingSucceeded : True
PingReplyDetails (RTT) : 14 ms
TraceRoute : {192.168.1.1, 10.0.0.1, 96.120.81.161, 68.86.143.149...}
The advantage of this structure is immediate. If you only want to extract the clean array of IP hops along the pathway, you do not need to parse text block by block. You can isolate the property directly:
(Test-NetConnection -ComputerName google.com -TraceRoute).TraceRoute
Advanced Parameters for Custom Traces
To customize how Test-NetConnection handles your network environment, utilize these advanced options:
- Limiting Hop Count (
-Hops): By default, a traceroute will attempt to scan up to 30 hops. If you are only troubleshooting local gateway or ISP issues and want to speed up execution, you can restrict the maximum hop count:Test-NetConnection -ComputerName google.com -TraceRoute -Hops 5 - Diagnostic Routing (
-DiagnoseRouting): If you are troubleshooting multi-homed servers (machines with multiple network cards or route tables), you can use this switch to analyze the local routing table and verify which physical interface and gateway PowerShell will select to reach the target destination.
Mastering Traceroutes in PowerShell 7+ (Core)
With the transition of PowerShell to a modern, open-source, cross-platform engine (PowerShell 7+), many of the underlying Windows-centric APIs changed. Because Test-NetConnection relies on Windows Management Instrumentation (WMI) and specific Windows network APIs, it is completely unavailable on Linux and macOS environments.
To bridge this gap, Microsoft fully rewrote the Test-Connection cmdlet in PowerShell Core. In PowerShell 7+, Test-Connection is your primary, cross-platform utility for pings and route tracing.
To run a traceroute in modern PowerShell, use the -Traceroute switch (note the lowercase "r" in the switch name compared to Windows PowerShell):
Test-Connection -TargetName google.com -Traceroute
The Streaming Advantage
Unlike Test-NetConnection in PowerShell 5.1, which hides progress until the entire trace is completed, Test-Connection -Traceroute in PowerShell 7+ streams results to the terminal in real-time, hop-by-hop. Each hop is returned as an independent PingStatus object.
This streaming capability is incredibly useful for scripting because you can immediately inspect the properties of each hop as they are discovered:
Test-Connection -TargetName google.com -Traceroute | Select-Object Hop, ProtocolAddress, ResponseTime
Bypassing DNS Lookups for Speed
One of the biggest complaints about traceroutes is the execution delay caused by DNS resolution. If an intermediate router does not have a reverse DNS pointer record, your query will hang while waiting for the DNS timeout. In PowerShell 7, DNS resolution is disabled by default. If you want to resolve hostnames, you must append the -ResolveDestination switch:
# Fast, IP-only traceroute (Default)
Test-Connection -TargetName google.com -Traceroute
# Slower traceroute with reverse DNS lookups enabled
Test-Connection -TargetName google.com -Traceroute -ResolveDestination
The TCP Traceroute Challenge: How to Trace Specific Ports
In modern network security, firewalls and cloud security groups routinely block, drop, or rate-limit ICMP traffic. Consequently, running a standard ICMP traceroute to an enterprise application server or a cloud database often results in endless timeouts (* * *) starting from the network gateway. However, your actual application port (such as TCP 443 for HTTPS or TCP 1433 for SQL Server) might be perfectly open and routing fine.
To diagnose these issues, you need to execute a powershell tcp traceroute—a trace that sends TCP SYN packets targeting a specific port rather than ICMP pings. This accurately maps the routing path that your actual application traffic takes.
The Common Pitfall: Combining -Port and -TraceRoute
When starting out, many administrators attempt to combine parameters within Test-NetConnection like this:
Test-NetConnection -ComputerName webserver.local -Port 443 -TraceRoute
Running this command will throw a critical syntax error:
Parameter set cannot be resolved using the specified named parameters.
This occurs because the cmdlet uses strictly defined, mutually exclusive parameter sets. The -Port parameter belongs to the RemotePort set, which tests simple end-to-end TCP socket connection (returning a boolean True or False). It cannot trace hops. The -TraceRoute parameter belongs to the ICMP set and cannot accept a custom TCP port.
Fortunately, you can easily bypass this limitation using the following four methods.
Method 1: Native Dual-Test Correlation (No Installation Required)
If you are on a restricted server and cannot install third-party tools, you can run a two-part diagnostic test to correlate the network behavior:
# Part 1: Gather the Layer 3 physical path topology
$Route = Test-NetConnection -ComputerName example.com -TraceRoute -WarningAction SilentlyContinue
# Part 2: Validate end-to-end Layer 4 port connectivity
$PortCheck = Test-NetConnection -ComputerName example.com -Port 443 -WarningAction SilentlyContinue
[PSCustomObject]@{
Destination = $Route.ComputerName
ResolvedIP = $Route.RemoteAddress
Port443Open = $PortCheck.TcpTestSucceeded
RouteCompleted = $Route.PingSucceeded
NetworkPath = $Route.TraceRoute -join " -> "
}
If Port443Open returns True but the traceroute times out with asterisks halfway, you immediately know that routing is fully operational for application traffic and the intermediate packet loss in the traceroute is simply a firewall discarding low-priority ICMP packets.
Method 2: Running tracetcp (Best Native Windows Utility)
If you need a true, hop-by-hop TCP traceroute on a specific port, the free, command-line utility tracetcp is the industry-standard tool for Windows. It generates TCP SYN packets on any port you specify, allowing you to bypass ICMP-blocking firewalls entirely.
- Download and install Npcap or WinPcap on your Windows host.
- Download
tracetcpfrom its release repository and extracttracetcp.exeto a folder included in your System PATH (e.g.,C:\Windows\System32). - From your PowerShell terminal, execute the powershell traceroute port check:
tracetcp google.com:443 -h 15
This outputs real-time, hop-by-hop latency and IP information targeting TCP port 443 directly in your console.
Method 3: Using Nmap within PowerShell
Nmap is a powerful network discovery scanner that includes a comprehensive traceroute engine. If Nmap is installed on your workstation, you can run a TCP trace targeting a specific port directly through PowerShell:
nmap --traceroute -p 443 google.com
PowerShell captures and displays Nmap’s output, allowing you to identify exactly where TCP traffic is dropping along the path.
Method 4: WSL (Windows Subsystem for Linux)
If you have WSL installed, you can drop into a bash context from PowerShell and utilize the native Linux tcptraceroute utility:
wsl tcptraceroute google.com 443
Automating Route Diagnostics (Practical Scripts)
One of the greatest benefits of running a traceroute powershell command over legacy command prompt tools is the ability to write automation scripts. Below are two production-ready scripts designed to run on schedules, audit network health, and log changes.
Script 1: Multi-Target Endpoint Route Auditor
This script reads a list of critical servers, identifies the host PowerShell version, executes the appropriate native traceroute command, and compiles the hops into a clean, structured CSV report on your desktop.
# List of critical server endpoints to check
$Endpoints = @("google.com", "github.com", "one.one.one.one")
$Report = [System.Collections.Generic.List[PSCustomObject]]::new()
Write-Host "Starting multi-target PowerShell traceroute audit..." -ForegroundColor Cyan
foreach ($Target in $Endpoints) {
Write-Host "Tracing route to: $Target..." -ForegroundColor Yellow
if ($PSVersionTable.PSVersion.Major -ge 6) {
# PowerShell 7+ Path
try {
$Hops = Test-Connection -TargetName $Target -Traceroute -ErrorAction Stop
foreach ($Hop in $Hops) {
$Report.Add([PSCustomObject]@{
TargetHost = $Target
HopNumber = $Hop.Hop
HopIP = $Hop.ProtocolAddress
LatencyMs = $Hop.ResponseTime
Status = "Success"
})
}
} catch {
$Report.Add([PSCustomObject]@{
TargetHost = $Target
HopNumber = 1
HopIP = "N/A"
LatencyMs = "N/A"
Status = "Failed: $_"
})
}
} else {
# Windows PowerShell 5.1 Path
$TraceResult = Test-NetConnection -ComputerName $Target -TraceRoute -WarningAction SilentlyContinue
if ($TraceResult.TraceRoute) {
$HopCounter = 1
foreach ($HopIP in $TraceResult.TraceRoute) {
$Report.Add([PSCustomObject]@{
TargetHost = $Target
HopNumber = $HopCounter
HopIP = $HopIP
LatencyMs = "N/A" # PS 5.1 TraceRoute property does not expose individual hop latency
Status = "Success"
})
$HopCounter++
}
} else {
$Report.Add([PSCustomObject]@{
TargetHost = $Target
HopNumber = 1
HopIP = "N/A"
LatencyMs = "N/A"
Status = "Failed"
})
}
}
}
# Export compilation to CSV file
$OutputPath = "$env:USERPROFILE\Desktop\Route_Diagnostics.csv"
$Report | Export-Csv -Path $OutputPath -NoTypeInformation
Write-Host "Audit complete! File saved to: $OutputPath" -ForegroundColor Green
Script 2: ISP Route Stability & Failover Monitor
During VPN handovers, ISP route shifts, or automated load-balancing switches, routing paths can change dynamically. This monitor script runs in an infinite loop, tracing the path to a designated public host every 15 seconds. If a change in the physical sequence of hops is detected, it logs the change with a precise timestamp to a persistent log file.
$TargetHost = "8.8.8.8"
$LogFile = "C:\temp\route_monitor_log.txt"
# Ensure destination logging directory exists
$LogDirectory = Split-Path $LogFile
if (-not (Test-Path $LogDirectory)) {
New-Item -ItemType Directory -Path $LogDirectory -Force | Out-Null
}
Write-Host "Monitoring path to $TargetHost. Press [Ctrl+C] to exit." -ForegroundColor Green
$LastKnownPath = ""
while ($true) {
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
if ($PSVersionTable.PSVersion.Major -ge 6) {
$Hops = Test-Connection -TargetName $TargetHost -Traceroute -ErrorAction SilentlyContinue |
Select-Object -ExpandProperty ProtocolAddress
$CurrentPath = $Hops -join " -> "
} else {
$Trace = Test-NetConnection -ComputerName $TargetHost -TraceRoute -WarningAction SilentlyContinue
$CurrentPath = $Trace.TraceRoute -join " -> "
}
if ($CurrentPath -and ($CurrentPath -ne $LastKnownPath)) {
$LogEntry = "[$Timestamp] ROUTE CHANGE DETECTED: $CurrentPath"
Write-Host $LogEntry -ForegroundColor Magenta
Add-Content -Path $LogFile -Value $LogEntry
$LastKnownPath = $CurrentPath
} elseif (-not $CurrentPath) {
$LogEntry = "[$Timestamp] ERROR: Destination host unreachable."
Write-Host $LogEntry -ForegroundColor Red
Add-Content -Path $LogFile -Value $LogEntry
}
Start-Sleep -Seconds 15
}
Frequently Asked Questions
Can you use the standard 'tracert' command in PowerShell?
Yes, absolutely. The classic tracert utility is a compiled system binary (tracert.exe) included with the Windows operating system. Because PowerShell executes standard system binaries seamlessly, typing tracert google.com will work perfectly. However, the output is raw, unformatted text (string data) rather than an object. This makes the output difficult to filter, slice, or integrate into automated diagnostic scripts compared to native cmdlets.
Why does Test-NetConnection -TraceRoute take so much longer to complete than tracert?
By default, Test-NetConnection performs a reverse DNS lookup (PTR query) for every single routing node it discovers. If an intermediate hop is a secure backbone or firewall with no configured reverse DNS record, the query must wait until its internal DNS timeout expires before moving to the next hop. Classic tracert performs lookups asynchronously or allows you to bypass host resolution completely with the -d switch.
What do asterisks (* * *) mean during a trace?
Asterisks indicate that a specific intermediate router along the path did not reply with an ICMP "Time Exceeded" packet within the timeout window. This is highly common on enterprise backbones and public ISP paths. Network administrators routinely block low-priority ICMP traffic on edge devices to prevent network mapping and conserve CPU resources. If your traceroute ultimately reaches the destination with stable round-trip times, intermediate asterisks do not represent an actual connectivity issue.
How can I run a traceroute on macOS or Linux using PowerShell?
In PowerShell 7+, you can use the cross-platform Test-Connection -Traceroute cmdlet on both macOS and Linux. However, because manipulating IP packet headers (such as setting custom Time-To-Live limits on raw sockets) requires low-level system permissions, you must run your PowerShell Core console as a superuser (e.g., sudo pwsh) to perform the trace successfully.
Conclusion
Upgrading your network diagnostic toolkit from the legacy, string-based CMD prompt to a dynamic, object-oriented powershell traceroute workflow is essential for modern system administrators and DevOps engineers. Utilizing Test-NetConnection -TraceRoute in Windows PowerShell 5.1 or transitioning to Test-Connection -Traceroute in PowerShell 7+ allows you to map paths, track latency, and automate your diagnostic reports. By understanding parameter limits, correlating dual port/trace tests, and utilizing advanced tools like tracetcp for TCP specific traces, you will identify and remediate network latency issues across your physical, on-premises, and cloud infrastructure faster and more accurately.





