Overriding Ping To Allow Pasting From The Chrome Address Bar With PowerShell
Posted on July 03, 2020
- and tagged as
- powershell
Frankly, I wasn’t sure whether to make a post about this or not, on one hand it’s utterly trivial, but on the other hand it fixes something that has bugged me for years and is probably annoying others. Seeing as it’s Friday after work and I’m still caffeinated, we’re pressing on.
The issue we’re dealing with today is that when you copy this text:
You end up with this:
The Chrome address bar simply hides the protocol (and trailing slash) to make things look cleaner, but it’s there and it gets copied. You now have to clean this up when pasting it into a ping command.
I do this often enough that it has become an annoyance to the point where the inconvenience now outweighs my laziness to do something about it.
Overriding native commands
We’ll do it by overriding the ping
command with a custom function. What happens if you have a function called ping
, but there is also a command called ping
? Which gets executed? This is covered in the official PowerShell docs on Command Precedence.
In summary, if there are multiple commands which can be executed for a given name, the following precedence order is applied:
- Alias
- Function
- Cmdlet
- Executable
Therefore, if we have a function and an executable both named ping
, the function is what will be executed.
Let’s create our new ping function.
function Ping {
$args = $args | % {$Hostname = ([System.Uri]$_).Host; if ($Hostname) {$Hostname} else {$_}}
ping.exe $args
}
All we’re doing here is taking our various arguments, typecasting them to a Uri
, and if the new object has a Host
property that is not $null
, we return that, otherwise we return the original value - this allows us to preserve other ping options, or already valid hostnames or IP addresses.
Let’s look at a few examples of this.
PS C:\> [System.URI]"http://somewebsite.com" | select Host
Host
----
somewebsite.com
Nice, that returns just the hostname we’re after. But what about other ping arguments, such as -t
?
PS C:\> [System.URI]"-t" | select Host
Host
----
Nothing, the Host
value is null, which means our script will return the original -t
value to the argument list.
The best way to make this function easily accessible is to put it into our $Profile
script (if you’d like to sync your profile across multiple computers check out this post on doing just that).
Let’s see some examples of our new ping in action.
Examples
Dealing with our original problem:
PS C:\> ping https://google.com
Pinging google.com [142.250.67.14] with 32 bytes of data:
Reply from 142.250.67.14: bytes=32 time=41ms TTL=112
Reply from 142.250.67.14: bytes=32 time=35ms TTL=112
Reply from 142.250.67.14: bytes=32 time=35ms TTL=112
Reply from 142.250.67.14: bytes=32 time=36ms TTL=112
Ping statistics for 142.250.67.14:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 35ms, Maximum = 41ms, Average = 36ms
Pasting in an entire URL with additional parameters
PS C:\> ping -n 2 https://stackoverflow.com/questions/7202157/why-does-return-the-string-10 -l 1200
Pinging stackoverflow.com [198.252.206.25] with 1200 bytes of data:
Reply from 198.252.206.25: bytes=1200 time=251ms TTL=46
Reply from 198.252.206.25: bytes=1200 time=245ms TTL=46
Ping statistics for 198.252.206.25:
Packets: Sent = 2, Received = 2, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 245ms, Maximum = 251ms, Average = 248ms
Even UNC paths are now correctly parsed if we happen to have that in our clipboard.
PS C:\> ping \\10.250.1.12\data -t
Pinging 10.250.1.12 with 32 bytes of data:
Reply from 10.250.1.12: bytes=32 time<1ms TTL=64
Reply from 10.250.1.12: bytes=32 time<1ms TTL=64
Reply from 10.250.1.12: bytes=32 time<1ms TTL=64
Ping statistics for 10.250.1.12:
Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
Control-C
Lastly, if we need to access the original ping command, we can still do that by using ping.exe
.
PS C:\> ping.exe https://google.com
Ping request could not find host https://google.com. Please check the name and try again.
Not sure how I managed to write 600+ words about this, but there you have it. Hopefully this is one less insignificant annoyance in your life.