Posts tagged PowerShell

Getting your public IP from a PowerShell script

I often work on computers at different locations, and often, I need to know what public IP I am using to connect to the internet. Of course, this is easy to find out - I can just go to a website that tells me my IP, such as http://myip.dk/.

But I find this to be suboptimal. If I am configuring something, finding the IP involves firing up a browser, going to the site, and copying the IP displayed. It is a speed bump when I am trying to be productive - and the display-my-ip sites are often covered in commercials, which I dislike.

So today, I decided to write a PowerShell script that can tell me my current public IP address. First, I needed a reliable way of finding it. Of course, I could just screen-scrape off a site such as http://myip.dk/, but it has some disadvantages. I can't know if the html structure will change - and it would mean that I would have to download all of the HTML just to get a few bytes of IP address. Furthermore, I don't know whether it would be legal at all.

Therefore, I started by writing a small ASP .NET HTTP handler, that could tell me my IP. I put the following simple code in the ProcessRequest method:

 1:     public void ProcessRequest (HttpContext context) {
 2:         context.Response.ContentType = "text/plain";
 3:         context.Response.AddHeader("X-RemoteIP", HttpContext.Current.Request.UserHostAddress);
 4:         context.Response.Write(HttpContext.Current.Request.UserHostAddress);        
 5:     }

This simply writes the IP address the handler is accessed with, to the response as well as to a custom http header. I then deployed this handler to my website.

Next, writing the PowerShell script, was equally simple; we can simply use the handy System.Net.WebClient class:

 1: $ipFinderHost = "http://www.somedomain.org/GetIP.ashx"
 2: $c = new-object System.Net.WebClient
 3: $c.DownloadString($ipFinderHost)

And voila, I have a PowerShell script that displays my public IP address. And, since I have the PowerShell Community Extensions installed, I can use the set-clipboard cmdlet to copy it to the clipboard.

 1: get-myip | set-clipboard

Much nicer than manually copying from the text in a browser :-) If you decide to use this script yourself, obviously you will need to change the URL in the script to where you have deployed the GetIP.ashx handler.


JAOO Day One

Today, I've been attending the first day at the JAOO Conference. It has been an interesting day, and I am amazed by all the very talented people that speaks here at the conference, as well as by the quality of the talks. I have been attending these sessions:

Opening Keynote: Where Are Programming Languages Going, by Anders Hejlsberg
In this talk, Anders presented his take on how the programming languages will be evolving in the future. One point made, was that programming languages has not evolved much over the last 25 years - which was exemplified by a "Hello world" program in Pascal versus one in C#. The C# one was neither the shortest nor the most concise one. Anders believes that we will se more implementation of what he calls "internal domain-specific-languages", such as LINQ. Furthermore, he thinks that in the future the gap between functional and imperative programming languages will diminish, since they are already today starting to borrow the best elements from each other. Finally, he talked about concurrency and in-language concurrency constructs such as isolation, which Anders predicts also will be part of the main-stream languages in the near future.

Continuous Integration
The Continuous Integration talk was a great introduction to me into Continuous integration, since it is something, that I have little to zero experience with. We do have a build server that does nightly builds at work, but as Chris Read, the speaker, pointed out, that is not CI, though it is a step on the way toward succesful CI.

Google Chrome: The Invisible Browser
This was a talk by Ben Goodger, the Google Chrome UI tech lead, about the minimalist Chrome UI and the architecture and decisions behind it. It was interesting, though there was not much new to learn here. (Or perhaps I should know better than to attend UI talks, when UI does not really interest me. I am trying to learn ;-) )

LING and C# 3.0
This was the second talk by Anders Hejlsberg this day, and featured the new features in C# 3.0. This was info that I knew (mostly) in advance, but Anders explained both the how and the why behind the features - which was really interesting.

PowerShell
The talk about PowerShell was really good; even for me who know and use PowerShell in advance. It got beyond the covers on why the architecture and implementation works as it does, which was interesting and enlightening, and I left with a better understanding of PowerShell.

The Scala Programming Language
Scala is a language for the JVM, that I did not know much about in advance. The talk was interesting, but in "real life", I am probably never going to use it.

Why Functional Programming (still) Matters
This talk by Erik Meijer was propably the most interesting and entertaining one on Day One of JAOO. With enthusiasm, Erik explained about side-effects and why they are bad and what one should do about them (make them explicit if they cannot be avoided). He also demonstrated a few side effects, that can hit you in C# or other main stream languages with closures and lambdas, which was a pleasant reminder for me.


Parsing XML with PowerShell

I'm addicted to PowerShell. This cool scripting environment is simple to use, and with very few lines of script; it is possible to accomplish tasks that otherwise often would be a lot of tedious work. (If we didn't have PowerShell, I would propably wip up a C# program to do the same, but PowerShell is really lightweight, is interactive and is generally very forgiving for small tasks where you just "want the job done".

As an example, today I needed to look at a log files generated by Visual Studio to figure out why the environment wouldn't start on my home PC. As it turns out, these log files are actually XML files. Of course I could have just started reading through the XML, but all the angle brackets confuses my brain; when I'm actually mostly interested in the text content of the log file.

So, five minutes later, this 3-line script; parse-vslog.ps1 was born:

1: param( [string]$file = $(throw "required parameter" ) )
2: $log = [xml](get-content $file)
3: $log.activity.entry | select record,type,description | format-table -wrap -auto

This is what happens in the script:

On line 1, we declare that we need a $file parameter (variables and parameters is prefixed with $ in PowerShell), that should be required.

On line 2 we use the get-content cmdlet to get the contents of a file. PowerShell has a lot of XML helping features, one of which is the ability to "cast" the content to XML using the [xml] construct. What really happens behind the scenes, is that PowerShell instantiates an XmlDocument and loads the text content of the file in that.

Last, on line 3, we take advantage of the fact that PowerShell let's us select XML nodes by using simple dotted notation. Here we are interested in all the the /activity/entry nodes. We pass the result along the pipeline and selects the 3 most important values using the select cmdlet. And, lastly, we format the output nicely with format-table, specifying that we would like the cmdlet to auto-select the column widths (-auto) and that text output should be wrapped on multiple lines (-wrap).

So insted of having to look at XML that goes on like this:

1: xml-stylesheet type="text/xsl" href="ActivityLog.xsl"?>
2: activity>
3:   entry>
4:     record>1record>
5:     time>2008/06/15 15:44:18.220time>
6:     type>Informationtype>
7:     source>Microsoft Visual Studiosource>
8:     description>Visual Studio Version: 9.0.21022.8description>
9:   entry>
10:   entry>
11:     record>2record>
12:     time>2008/06/15 15:44:18.221time>
13:     type>Informationtype>
14:     source>Microsoft Visual Studiosource>
15:     description>Running in User Groups: Administrators Usersdescription>
16:   entry>
17:   entry>
18:     record>3record>
19:     time>2008/06/15 15:44:18.221time>
20:     type>Informationtype>
21:     source>Microsoft Visual Studiosource>
22:     description>ProductID: 91904-270-0003722-60402description>
23:   entry>
24:   entry>
25:     record>19record>
26:     time>2008/06/15 15:44:19.094time>
27:     type>type>
28:     source>Microsoft Visual Studiosource>
29:     description>Destroying Main Windowdescription>
30:   entry>
31: activity>
32:  

Now, I can get this much nicer output in the console (note that the XML above has been shortened for the blog. It was actually around 150 lines):

record type        description
------ ----        -----------
1      Information Visual Studio Version: 9.0.21022.8
2      Information Running in User Groups: Administrators Users
3      Information ProductID: 91904-270-0003722-60402
4      Information Available Drive Space: C:\ drive has 42128211968 bytes; D:\ drive has 38531145728 bytes; E:\ drive h
                   as 127050969088 bytes; F:\ drive has 117087354880 bytes
5      Information Internet Explorer Version: 7.0.6001.18063
6      Information Microsoft Data Access Version: 6.0.6001.18000
7      Information .NET Framework Version: 2.0.50727.1434
8      Information MSXML Version: 6.20.1076.0
9      Information Loading UI library
10     Information Entering function CVsPackageInfo::HrInstantiatePackage
11     Information Begin package load [Visual Studio Source Control Integration Package]
12     Information Entering function CVsPackageInfo::HrInstantiatePackage
13     Information Begin package load [team foundation server provider stub package]
14     Information End package load [team foundation server provider stub package]
15     Information End package load [Visual Studio Source Control Integration Package]
16     Information Entering function VBDispatch::GetTypeLib
17     Information Entering function LoadDTETypeLib
18     Error       Leaving function LoadDTETypeLib
19                 Destroying Main Window
 

I think this is a good representative of the strength of PowerShell. Using only a few lines of script and a minimum of time, I created a reusable script, that will probaply save a lot of time in the future.