The Surly Admin

Father, husband, IT Pro, cancer survivor

Playing with Invoke-WebRequest – What is my IP Address?

Another script came through on Spiceworks here, and I liked the idea of it.  Not to mention I thought I could improve on it a bit using PowerShell.  It was also a good excuse to practice using Invoke-WebRequest which I haven’t had a lot of projects that use it!

vbScript

First off, the script takes advantage of a cool web address from Dyndns.org, called CheckIP.  This is a cool site I was unaware of (I’ve always used Whatismyip.com) and returns a nice simple webpage with the public IP address you’re surfing from.  As usual, the vbScript outputs text, which isn’t very useful from a PowerShell perspective so we’ll need to convert to a PSObject.  Also, it took the vbScript 4 lines to get the information while we can compress that into a single line.  The script than uses standard text manipulation to locate the IP address.  This is ok, but one problem is if Dyndns.org ever decides to change the output of this page the script will immediately stop working.

So how do we make a PowerShell script out of it?  How do we parameterize it so we can change things if needed?  And what if Dyndns.org decides to change the website (because, like, that never happens)?

Invoke-WebRequest

First, we’re going to see if we can even get this to work at all.  To query websites with PowerShell we use the Invoke-WebRequest cmdlet.  So let’s give it go:

invoke1Looking good so far.  The next step is trying to find the IP address inside the URL text.  Instead of trying to use SubString, and IndexOf and all of those text manipulation techniques I decided to use RegEx.  This is exactly what RegEx (Regular Expressions) are meant for and when using the match operator in PowerShell that will automatically create the $Matches variable which will hold our data in it.  That way, no matter where the IP address is in the web page, RegEx will find it for me.  I’ve mentioned this before, but my RegEx fu leaves a lot to be desired so I hit up Google for a good RegEx for finding IP addresses.  Second link lead me to O’Reilly Answers and this post.  So let’s take it for a spin and see what we get:

invoke2Sometimes it comes together easier than you expect!  Here’s the about $Matches too, it’s not an object, like the output above suggests.  It’s actually an array.  If you typed $Matches.Value you wouldn’t actually get anything.  But Matches[0] would get you the first match, Matches[1] the second and so on (assuming more than one match was found).  So just slap that into a PSObject and we’re done, right?  But, of course, I can never just do things that easy right?  We need a little bit more.  Wouldn’t it be nice if not only we could get the IP address, but also get the the name?  That means we need to do a reverse DNS lookup on the IP address.  If I knew everyone who might be running this script had Windows 8.1 or Windows Server 2012 I could use the new Resolve-DNSName cmdlet to resolve this IP address, but the reality is that most admins who run this will not be using that so we need a solution that supports older clients.  Luckily there is a WMI class for doing this kind of thing, something I’ve used in the past with my Network Discovery script.  Here’s how you would use that class, let’s assume $IP is the IP address we discovered from our Invoke-WebRequest:

$Ping = Get-WMIObject Win32_PingStatus -Filter "Address = '$IP' AND ResolveAddressNames = TRUE"
If ($Ping.StatusCode -eq 0)
{ $ComputerName = $Ping.ProtocolAddressResolved
}
Else
{ $ComputerName = "Unable to resolve"
}

I’ve also changed how I display code snippets in the blog.  The ScriptBlock code in WordPress has a depressing tendency to convert double quotes, greater than and lesser than symbols to their HTML equivalent.  Can’t tell you how many times I’ve had to go back and edit blog posts to change them back to their native symbols and I’m tired of it!  Hopefully this will resolve the problem once and for all.  The code snippet is a “gist” from Github.  You can sign up for free and create your own and link them and WordPress will embed them nicely for you.  So, at least, there’s that!

And that’s really it.  I’ve wrapped some error trapping in there, and I’ve also add a parameter for the URL.  In theory you could point this script to any web page that produces your public IP address, as long as it’s the first IP address in the HTML stream that returns to you.

Here’s the final result:

invokefinal

Get-WhatIsMyIP

Advertisement

December 21, 2013 - Posted by | PowerShell | ,

2 Comments »

  1. I hardly drop remarks, however i did a few searching and wound up here Playing with Invoke-WebRequest – What is my IP Address?
    « The Surly Admin. And I do have 2 questions for you if you
    don’t mind. Is it simply me or does it seem like some of these remarks appear like they are coming from brain dead individuals?
    😛 And, if you are writing on additional sites, I’d like to keep up with everything new
    you have to post. Could you make a list of the complete urls of
    all your public sites like your linkedin profile, Facebook page or twitter feed?

    Comment by perfume mujer | March 16, 2014 | Reply

    • No other writing, but I can be found quite easily at Spiceworks in the IT Programming and PowerShell forums. I also post pretty regularly at PowerShell.com.

      Comment by Martin9700 | March 16, 2014 | Reply


Leave a Reply

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

WordPress.com Logo

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

Twitter picture

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

Facebook photo

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

Connecting to %s

%d bloggers like this: