Skip to content

Instantly share code, notes, and snippets.

@gravejester
Last active April 3, 2018 16:26
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gravejester/5041912 to your computer and use it in GitHub Desktop.
Save gravejester/5041912 to your computer and use it in GitHub Desktop.
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: https://snoj.us/75/traceroute-wit…
function Trace-Route {
<#
.SYNOPSIS
Trace the route between source computer and a target machine.
.DESCRIPTION
Trace the route between source computer and a target machine.
.EXAMPLE
Trace-Route Computer01
Perform trace route to Computer01
.EXAMPLE
Trace-Route -Target www.microsoft.com -ResolveHostname
Perform trace route to www.microsoft.com and try to resolve hostname for each hop.
Note! This will slow down the function somewhat.
.NOTES
Author: Øyvind Kallstad
Date: 28.10.2014
Version: 1.1
#>
[CmdletBinding()]
param(
# Hostname or IP to trace to.
[Parameter(Position = 0, ValueFromPipeline = $true)]
[string] $Target = $env:COMPUTERNAME,
# Set starting hop.
[Parameter()]
[int] $BeginHop = 1,
# Set maximum number of hops.
[Parameter()]
[int] $MaxHops = 30,
# Define timeout in milliseconds.
[Parameter()]
[int] $Timeout = 1000,
# Try to resolve hostname for IP in each hop.
[Parameter()]
[switch] $ResolveHostname = $false
)
# verify that we can reach target system
try{
$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"
exit
}
}
catch{
Write-Warning "Unable to resolve target system $Target"
exit
}
# 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
}
else{
$ip = '*'
}
# get roundtrip time
$roundtripTime = $pingReply.RoundtripTime
# get status
$hopStatus = $pingReply.Status
# resolve hostname
if ($ResolveHostname) {
try{
$resolvedHostname = "[$(([System.Net.Dns]::GetHostEntry($ip)).HostName)]"
}
catch{
$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}
}
}
@machammarj
Copy link

Hi!
Very nice script!

Do you know if it is possible to have a script that checks ff the tracert has a specific IP?

I would like to check if route has changed from Link1 to Link2.

Many thanks in advance!

@jnic335
Copy link

jnic335 commented Apr 3, 2018

Hi Machammarj,

Here is a way to do a specific IP address in BATCH and not in powershell as I needed to do the same thing. You will need an input file with a list of IP address on a new line.

`@echo off
setlocal enabledelayedexpansion

set OUTPUT_FILE=ips.txt
set IP_FILE=output.txt
set VIP_FILE=EXTERNAL_VIP.txt

set DC=""
set temp=""
set route_address=""

nul copy nul %IP_FILE%

for /f %%k in (%VIP_FILE%) do (
tracert.exe -4 -d -h 15 -w 300 %%k|Findstr /C:"ms" > %OUTPUT_FILE%
::setting max hops to 20 and timeout to 50
for /f "tokens=8 delims= " %%i in (%OUTPUT_FILE%) do (
set route_ip="%%i"
ECHO !route_ip! | Findstr /C:"10.1." >nul & IF ERRORLEVEL 1 ( set temp="" ) else ( set DC=AT
set route_address=!route_ip!)
ECHO !route_ip! | Findstr /C:"10.6." >nul & IF ERRORLEVEL 1 ( set temp="" ) else ( set DC=ORD
set route_address=!route_ip!)
)
echo %%k is routing from !route_address! in !DC!>>%IP_FILE%
set DC=""
set route_address=""
)

%IP_FILE%`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment