For some reason I wanted to write a trace route script in PowerShell, but decided to run it through Google first to see if it had been done. Surprisingly few results came up, and as far as I can tell, only one true PowerShell script doing Trace Route without just being a wrapper for tracert or something similar:

Naturally I wanted to tweak it and give it my personal touch, and here is my result:

function Trace-Route {
Trace the route between source computer and a target machine.
Trace the route between source computer and a target machine.
Trace-Route Computer01
Perform trace route to Computer01
Trace-Route -Target -ResolveHostname
Perform trace route to and try to resolve hostname for each hop.
Note! This will slow down the function somewhat.
Author: Øyvind Kallstad
Date: 28.10.2014
Version: 1.1
# Hostname or IP to trace to.
[Parameter(Position = 0, ValueFromPipeline = $true)]
[string] $Target = $env:COMPUTERNAME,
# Set starting hop.
[int] $BeginHop = 1,
# Set maximum number of hops.
[int] $MaxHops = 30,
# Define timeout in milliseconds.
[int] $Timeout = 1000,
# Try to resolve hostname for IP in each hop.
[switch] $ResolveHostname = $false
# verify that we can reach target system
$ping = New-Object System.Net.NetworkInformation.Ping
$pingResult = $ping.Send($Target)
if(-not($pingResult.Status -eq 'Success')){
Write-Warning "Unable to resolve target system $Target"
Write-Warning "Unable to resolve target system $Target"
# define some data to send
$sendBytes = @([byte][char]'a'..[byte][char]'z')
for($i = $BeginHop; $i -lt $MaxHops; $i++) {
# define ping options; set start hop and fragmentation to true
$pingOptions = new-object System.Net.NetworkInformation.PingOptions $i, $true
# perform ping
$pingReply = $ping.Send($Target, $Timeout, $sendBytes, $pingOptions)
# get ip for current hop if possible
if($pingReply.Address -ne $null){
$ip = $pingReply.Address
$ip = '*'
# get roundtrip time
$roundtripTime = $pingReply.RoundtripTime
# get status
$hopStatus = $pingReply.Status
# resolve hostname
if ($ResolveHostname) {
$resolvedHostname = "[$(([System.Net.Dns]::GetHostEntry($ip)).HostName)]"
$resolvedHostname = ''
# create custom object and send to pipeline
Write-Output ([PSCustomObject] [Ordered] @{
Hop = $i.ToString()
IP = "$($ip) $($resolvedHostname)"
Status = $hopStatus
RoundtripTime = $roundtripTime
# clean up
Remove-Variable ip, roundtripTime, hopStatus, resolvedHostname ErrorAction 'SilentlyContinue'
# stop loop if current ip matches the target ip
if($pingReply.Address -eq $pingResult.Address){break}

view raw


hosted with ❤ by GitHub

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s