Hey, Scripting Guy! I have a script that uses Netsh.exe to return information from my DHCP servers; all that information is then written to a text file. That works great, except that I need to be able to parse the data and pull out any IP addresses included in that information. How can I write a script that extracts just the IP addresses from a text file?
— MJ
Hey, MJ. You know, a lot of people are mystified as to why we Scripting Guys do a daily scripting column. “Doesn’t that become a big hassle to have to write a new column every day?” they ask. “Isn’t it hard to come up with new ideas and new things to write about? Wouldn’t it be easier to be a slacker like Scripting Guy Jean Ross, and just write one new column a month rather than one new column a day?”
Well, needless to say, the answer to all those questions is, “Yes.” Yes, it is a hassle; yes, it is hard to come up with new ideas and new things to write about; and yes, we would like to be like Scripting Guy Jean Ross. (Hey, who wouldn’t?) So then why do we continue to write a new Hey, Scripting Guy! each and every day?
Well, that’s partly due to our desire to best Scripting Guy Jean Ross at every turn. (Yo, Jean Ross, check the score: Hey, Scripting Guy! 781 columns, Sesame Script a measly 26 columns!) More importantly, however, publishing a new column each and every day gives us a chance to address your questions and concerns when it comes to system administration scripting.
Not to mention the fact that it also gives us a venue for shamelessly promoting everything the Scripting Guys do. You know, things like traveling to Barcelona, Spain for the 2007 TechEd IT Forum, which modestly bills itself as:
“Microsoft’s premier European conference designed to provide IT professionals with technical training, information and community resources to build, plan, deploy and manage the secure connected enterprise using Microsoft infrastructure products and technologies.”
They’ve got us convinced.
As you might expect, the Scripting Guys are looking forward to the trip: this marks the first time we’ve ever been let out of the country to attend a conference. (Of course, whether or not they’ll let us back into the country has yet to be determined.) Scripting Guys Jean Ross and Greg Stemp will be manning a booth in the Ask the Experts section of the convention center; Greg will be there each and every day, Jean will probably show you up once and call it good. (Editor’s Note: At least Jean will show up, which is more than Greg did at TechEd 2007 in Orlando.) Will we be available to chat and to answer questions? Of course we will. Will we be giving away hundreds of copies of Dr. Scripto’s Fun Book, as well as a whole bunch of Dr. Scripto bobblehead dolls? Of course we will. Will we let you throw darts at a big huge dartboard? Greg says yes we will; Jean says – well, never mind. We’re not allowed to print the things that Jean says any time Greg comes up with a new idea.
Anyway, if you haven’t signed up for the TechEd IT Forum there’s still plenty of time to do so. And if you won’t register for yourself, then do it for the Scripting Guys. After all, we have no desire to explain to our manager why he spent all that money to send us to Barcelona only to have no else show up.
Besides, the scripting world owes us one. After all, aren’t we the ones who showed you all how to write a script that can extract IP addresses from a text file?
Oh, we didn’t show you a script like that? Well, now we have:
Const ForReading = 1Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objFile = objFSO.OpenTextFile(“C:\Scripts\Test.txt”, ForReading)
strSearchString = objFile.ReadAll
objFile.Close
Set objRegEx = CreateObject(“VBScript.RegExp”)
objRegEx.Global = True objRegEx.Pattern = “\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}”
Set colMatches = objRegEx.Execute(strSearchString)
If colMatches.Count > 0 Then For Each strMatch in colMatches Wscript.Echo strMatch.Value Next End If
Before we launch into an explanation of how the script works we should give you a peek at MJ’s text file. That file, which uses data retrieved (and formatted) by Netsh.exe, looks a little something like this:
========================================================================== Scope Address – Subnet Mask – State -Scope Name -Comment 192.168.120.0 – 255.255.255.0 – Active -New York, Class C – New York, NY C Total No. of Scopes = 1
As you can see, we have two IP addresses in this file: 192.168.120.0 and 255.255.255.0.
Note. OK, technically, 255.255.255.0 is the subnet mask, you may or may not want your script to return this value. The script we just showed you returns the subnet mask. What if you don’t want the script to return the subnet mask? Relax; we’ll show you how to do that in just a minute or so. |
But first things first. The script starts out by defining a constant named ForReading and setting the value to 1; we’ll use this constant when we open the text file. After defining the constant, we create an instance of the Scripting.FileSystemObject, then use the OpenTextFile method to open the file C:\Scripts\Test.txt for reading:
Set objFile = objFSO.OpenTextFile(“C:\Scripts\Test.txt”, ForReading)
As soon as the file is open, we use the ReadAll method to read in the entire contents of that file and store that information in a variable named strSearchString:
strSearchString = objFile.ReadAll
And then we simply call the Close method to close the file. At that point, we’re done.
Well, OK, we’re done with the text file; when it comes to extracting IP addresses, however, well, there we still have a little bit of work to do. But that’s all right; the Scripting Guys have never shied away from a little hard work.
Note. Not that we’ve ever actually done any hard work, mind you. We’ve just never shied away from it. |
As MJ noted in his email, these IP addresses could be just about anything; there’s no guarantee that they all start with, say, 192.168. Does that complicate the issue of locating these IP addresses? Believe it or not, it doesn’t. At least not if you use regular expressions in your script.
We’re not going to discuss the theory of regular expressions today; for that, you might check out the webcast String Theory for System Administrators: An Introduction to Regular Expressions, presented by the late, great Dean Tsaltas.
Note. OK, technically Dean isn’t really dead; he just moved to Canada. But that’s pretty much the same thing, right? |
Note to our loyal Canadian readers. We’re just joking. The Scripting Guys have nothing against Canada; in fact, some of our best friends are Canadians. Like who? Um, well … like the late, great Dean Tsaltas, that’s who. |
At any rate, in order to use regular expressions within our script we first need to create an instance of the VBScript.RegExp object:
Set objRegEx = CreateObject(“VBScript.RegExp”)
As soon as we create the object we then set the Global property to True; that tells the regular expressions object that we want to search for all the IP addresses in our search string. (If we didn’t set this to True the script would stop after finding the first IP address. Needless to say, that would be a problem if the file actually contains multiple IP addresses.)
That brings us to this line of code:
objRegEx.Pattern = “\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}”
As it turns out, the Pattern property represents the value that we’re looking for. (In this case, an IP address.) We’ll explain what that cryptic-looking pattern means in just a second. Before we do that, however, let’s take a few minutes to meditate on the nature of IP addresses. What is an IP address? Well, in general, an IP address consists of:
• |
Anywhere from 1 to 3 digits (the values 0 through 9) followed by a period (e.g., 192.) |
• |
Anywhere from 1 to 3 digits followed by a second period (e.g., 168.) |
• |
Anywhere from 1 to 3 digits followed by one more period (e.g., 120.) |
• |
Anywhere from 1 to 3 digits (e.g., 1) |
Believe it or not, that’s an awfully good description of our search pattern as well. The construction \d{1,3} means “Find some digits; there must be at least one digit (1) but no more than three digits (3).” The construction \. Means “Find a dot.” If you follow the pattern all the way through, what search criteria do we end up with? You got it:
1 to 3 digits (the values 0 through 9) followed by a period, then 1 to 3 digits followed by a second period, then 1 to 3 digits followed by one more period, then 1 to 3 final digits.
Crazy, huh? But it all works.
After we define the search pattern our next step is to call the Execute method and perform a regular expressions search on the file contents; that’s what we do here:
Set colMatches = objRegEx.Execute(strSearchString)
If the Execute method finds any text matching the search pattern, that matching text will be stored in a collection named colMatches. That means we can determine whether or not any IP addresses appear in the file simply by checking to see if the collection’s Count property is greater than 0:
If colMatches.Count > 0 Then
If the Count property is greater than 0 then we set up a For Each loop to loop through all the items in that collection. Inside that loop we do nothing more complicated than echo back the match Value (that is, the text that met the search pattern):
Wscript.Echo strMatch.Value
What do we get back when we run this script against MJ’s sample dataset? This is what we get back:
192.168.120.0 255.255.255.0
Don’t want the subnet mask to be included? That’s fine; just add an If Then statement to your For Each loop and filter out any IP addresses that begin with 255. That’s something you can do by using the Left function to determine whether or not the first three characters in the value are equal to 255:
For Each strMatch in colMatches If Left(strMatch.Value, 3) <> “255” Then Wscript.Echo strMatch.Value End If Next
Run this modified script and you’ll get back the following:
192.168.120.0
Bye-bye subnet mask.
And hello, Barcelona. If you’re planning on attending the IT Forum in Barcelona (November 12-16) drop us a line and let us know (and be sure to pop by the Ask the Experts section and say hi. Oh, and if you know of any good restaurants or any fun things to do in Barcelona we’d appreciate hearing about those as well. After all, even Scripting Guy Jean Ross has to eat.
Well, once a month, anyway.
0 comments