1

I'm trying to colour the lines green, yellow and red within powershell depending on the latency in milliseconds. Our remote workflow dictates that anything over 40ms is bad, so I want this to be visually represented to people who run the test, which will be wrapped as exe for them to download and run if they need.

  • 1-19ms = Green
  • 20-39ms = Yellow
  • 40-500ms = Red
  • "request timed out" = Red

However, when I try to put this down in ISE it seems to not be behaving as expected. It often returns just one solid colour for all lines and sometimes it completely misses out some lines in the traceroute test. I've deliberately chosen a random Australian IP address to run the test on as it's very far away and should give a good mix of low to high latency as the hops go on and on.

Can anyone suggest where I may have gone wrong?

$traceroute = tracert 47.74.90.56

foreach ($trace in $traceroute)
{
if ($trace -Match '[1-9] ms' )
{
write-host "$trace" -ForegroundColor green
}
elseif ($trace -Match 'request timed out' )
{
write-host "$trace" -ForegroundColor red
}
elseif ($trace -Match '[1-0][1-9] ms' )
{
write-host "$trace" -ForegroundColor green
}
elseif ($trace -Match '[2-3][0-9] ms' )
{
write-host "$trace" -ForegroundColor yellow
}
elseif ($trace -Match '[4-9][0-9] ms' )
{
write-host "$trace" -ForegroundColor red
}
elseif ($trace -Match '[1-9][0-9][0-9] ms' )
{
write-host "$trace" -ForegroundColor red
}
}

2 Answers 2

1

You need a space at the beginning of your regex patterns. Otherwise, this line will almost always match:

# matches '21 ms' and '199 ms'
if ($trace -Match '[1-9] ms') {}

In more recent versions of powershell, this line will error because [1-0] is in reverse order:

# will also match '111 ms'
elseif ($trace -Match '[1-0][1-9] ms' ) {}

Invalid pattern '[1-0][1-9] ms' at offset 4. [x-y] range in reverse order.

I also recommend using switch for comparisons like this, but just for readability:

$traceroute = tracert $address

foreach ($trace in $traceroute) {
  switch -Regex ($trace){
    ' [1-9] ms'          { write-host "$trace" -F green;  break }
    'request timed out'  { write-host "$trace" -F red;    break }
    ' [01][1-9] ms'      { write-host "$trace" -F green;  break }
    ' [2-3][0-9] ms'     { write-host "$trace" -F yellow; break }
    ' [4-9][0-9] ms'     { write-host "$trace" -F red;    break }
    ' [1-9][0-9][0-9] ms'{ write-host "$trace" -F red;    break }
  }
}
1
  • Excellent, I didn't realise a space was required and that's fixed it! the switch makes total sense here as well. Thank you!
    – Mastaxx
    Commented Feb 2, 2023 at 11:01
1
  1. Line 13: elseif ($trace -Match '[1-0][1-9] ms' ) -- [1-0] is backwards, not accepted.
  2. While this does work, I'd find it easier to understand and less likely to break, e.g. due to other characters, such as <1 ms, if the output were converted to integer and compared as such.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .