{"id":63923,"date":"2007-09-28T02:18:00","date_gmt":"2007-09-28T02:18:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/09\/28\/how-can-i-retrieve-ip-addresses-and-only-ip-addresses-from-a-text-file\/"},"modified":"2007-09-28T02:18:00","modified_gmt":"2007-09-28T02:18:00","slug":"how-can-i-retrieve-ip-addresses-and-only-ip-addresses-from-a-text-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-retrieve-ip-addresses-and-only-ip-addresses-from-a-text-file\/","title":{"rendered":"How Can I Retrieve IP Addresses (and Only IP Addresses) From a Text File?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"> \n<P>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?<BR><BR>&#8212; MJ<\/P><IMG height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\"><\/A> \n<P>Hey, MJ. You know, a lot of people are mystified as to why we Scripting Guys do a daily scripting column. \u201cDoesn\u2019t that become a big hassle to have to write a new column every day?\u201d they ask. \u201cIsn\u2019t it hard to come up with new ideas and new things to write about? Wouldn\u2019t it be easier to be a slacker like Scripting Guy Jean Ross, and just write <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/begin\/archive.mspx\"><B>one new column a month<\/B><\/A> rather than one new column a <I>day<\/I>?\u201d<\/P>\n<P>Well, needless to say, the answer to all those questions is, \u201cYes.\u201d Yes, it <I>is<\/I> a hassle; yes, it <I>is<\/I> hard to come up with new ideas and new things to write about; and yes, we <I>would<\/I> like to be like Scripting Guy Jean Ross. (Hey, who wouldn\u2019t?) So then why do we continue to write a new <I>Hey, Scripting Guy!<\/I> each and every day?<\/P>\n<P>Well, that\u2019s partly due to our desire to best Scripting Guy Jean Ross at every turn. (Yo, Jean Ross, check the score: <I>Hey, Scripting Guy!<\/I> 781 columns, <I>Sesame Script<\/I> 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.<\/P>\n<P>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 <A href=\"http:\/\/www.mseventseurope.com\/teched\/07\/itforum\/Content\/Pages\/Default.aspx\" target=\"_blank\"><B>2007 TechEd IT Forum<\/B><\/A>, which modestly bills itself as:<\/P>\n<P>\u201cMicrosoft\u2019s 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.\u201d<\/P>\n<P>They\u2019ve got us convinced.<\/P>\n<P>As you might expect, the Scripting Guys are looking forward to the trip: this marks the first time we\u2019ve ever been let out of the country to attend a conference. (Of course, whether or not they\u2019ll let us back <I>into<\/I> 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. <I>(<\/I><I>Ed<\/I><I>itor\u2019s Note: At least Jean <\/I>will<I> show up, which is <\/I><A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/teched07\/monday.mspx\"><B><I>more than Greg did at TechEd 2007 in Orlando<\/I><\/B><\/A><I>.)<\/I> Will we be available to chat and to answer questions? Of course we will. Will we be giving away hundreds of copies of <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/teched07\/swag.mspx\"><B>Dr. Scripto\u2019s Fun Book<\/B><\/A>, as well as a whole bunch of <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/bobbles.mspx\"><B>Dr. Scripto bobblehead dolls<\/B><\/A>? Of course we will. Will we let you throw darts at a big huge dartboard? Greg says yes we will; Jean says \u2013 well, never mind. We\u2019re not allowed to print the things that Jean says any time Greg comes up with a new idea.<\/P>\n<P>Anyway, if you haven\u2019t <A href=\"http:\/\/www.mseventseurope.com\/teched\/07\/itforum\/Content\/Pages\/Registration.aspx\" target=\"_blank\"><B>signed up<\/B><\/A> for the TechEd IT Forum there\u2019s still plenty of time to do so. And if you won\u2019t 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. <\/P>\n<P>Besides, the scripting world owes us one. After all, aren\u2019t we the ones who showed you all how to write a script that can extract IP addresses from a text file?<\/P>\n<P>Oh, we <I>didn\u2019t<\/I> show you a script like that? Well, now we have:<\/P><PRE class=\"codeSample\">Const ForReading = 1<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForReading)<\/p>\n<p>strSearchString = objFile.ReadAll<\/p>\n<p>objFile.Close<\/p>\n<p>Set objRegEx = CreateObject(&#8220;VBScript.RegExp&#8221;)<\/p>\n<p>objRegEx.Global = True   \nobjRegEx.Pattern = &#8220;\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}&#8221;<\/p>\n<p>Set colMatches = objRegEx.Execute(strSearchString)  <\/p>\n<p>If colMatches.Count &gt; 0 Then\n    For Each strMatch in colMatches   \n       Wscript.Echo strMatch.Value\n    Next\nEnd If\n<\/PRE>\n<P>Before we launch into an explanation of how the script works we should give you a peek at MJ\u2019s text file. That file, which uses data retrieved (and formatted) by Netsh.exe, looks a little something like this:<\/P><PRE class=\"codeSample\">==========================================================================\nScope Address        &#8211; Subnet Mask                  &#8211; State                      -Scope Name            -Comment\n 192.168.120.0        &#8211; 255.255.255.0               &#8211; Active                     -New York, Class C    &#8211; New York, NY C\n Total No. of Scopes = 1\n<\/PRE>\n<P>As you can see, we have two IP addresses in this file: 192.168.120.0 and 255.255.255.0. <\/P>\n<TABLE class=\"dataTable\" id=\"EZF\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. 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\u2019t <I>want<\/I> the script to return the subnet mask? Relax; we\u2019ll show you how to do that in just a minute or so.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>But first things first. The script starts out by defining a constant named ForReading and setting the value to 1; we\u2019ll use this constant when we open the text file. After defining the constant, we create an instance of the <B>Scripting.FileSystemObject<\/B>, then use the <B>OpenTextFile<\/B> method to open the file C:\\Scripts\\Test.txt for reading:<\/P><PRE class=\"codeSample\">Set objFile = objFSO.OpenTextFile(&#8220;C:\\Scripts\\Test.txt&#8221;, ForReading)\n<\/PRE>\n<P>As soon as the file is open, we use the <B>ReadAll<\/B> method to read in the entire contents of that file and store that information in a variable named strSearchString:<\/P><PRE class=\"codeSample\">strSearchString = objFile.ReadAll\n<\/PRE>\n<P>And then we simply call the <B>Close<\/B> method to close the file. At that point, we\u2019re done.<\/P>\n<P>Well, OK, we\u2019re done with the <I>text file<\/I>; when it comes to extracting IP addresses, however, well, there we still have a little bit of work to do. But that\u2019s all right; the Scripting Guys have never shied away from a little hard work.<\/P>\n<TABLE class=\"dataTable\" id=\"EAH\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. Not that we\u2019ve ever actually <I>done<\/I> any hard work, mind you. We\u2019ve just never shied away from it.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>As MJ noted in his email, these IP addresses could be just about anything; there\u2019s no guarantee that they all start with, say, <B>192.168<\/B>. Does that complicate the issue of locating these IP addresses? Believe it or not, it doesn\u2019t. At least not if you use regular expressions in your script.<\/P>\n<P>We\u2019re not going to discuss the theory of regular expressions today; for that, you might check out the webcast <A href=\"http:\/\/www.microsoft.com\/events\/EventDetails.aspx?CMTYSvcSource=MSCOMMedia&amp;Params=%7eCMTYDataSvcParams%5e%7earg+Name%3d%22ID%22+Value%3d%221032271679%22%2f%5e%7earg+Name%3d%22ProviderID%22+Value%3d%22A6B43178-497C-4225-BA42-DF595171F04C%22%2f%5e%7earg+Name%3d%22lang%22+Value%3d%22en%22%2f%5e%7earg+Name%3d%22cr%22+Value%3d%22US%22%2f%5e%7esParams%5e%7e%2fsParams%5e%7e%2fCMTYDataSvcParams%5e\" target=\"_blank\"><B>String Theory for System Administrators: An Introduction to Regular Expressions<\/B><\/A>, presented by the late, great Dean Tsaltas. <\/P>\n<TABLE class=\"dataTable\" id=\"E2H\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\"><B>Note<\/B>. OK, technically Dean isn\u2019t really dead; he just moved to Canada. But that\u2019s pretty much the same thing, right?<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<TABLE class=\"dataTable\" id=\"EHAAC\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P><B>Note to our loyal Canadian readers<\/B>. We\u2019re just <I>joking<\/I>. The Scripting Guys have nothing against Canada; in fact, some of our best friends are Canadians.<\/P>\n<P>Like who? Um, well \u2026 like the late, great Dean Tsaltas, that\u2019s who.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>At any rate, in order to use regular expressions within our script we first need to create an instance of the <B>VBScript.RegExp<\/B> object:<\/P><PRE class=\"codeSample\">Set objRegEx = CreateObject(&#8220;VBScript.RegExp&#8221;)\n<\/PRE>\n<P>As soon as we create the object we then set the <B>Global<\/B> property to True; that tells the regular expressions object that we want to search for <I>all<\/I> the IP addresses in our search string. (If we didn\u2019t 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.)<\/P>\n<P>That brings us to this line of code:<\/P><PRE class=\"codeSample\">objRegEx.Pattern = &#8220;\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}&#8221;\n<\/PRE>\n<P>As it turns out, the <B>Pattern<\/B> property represents the value that we\u2019re looking for. (In this case, an IP address.) We\u2019ll explain what that cryptic-looking pattern means in just a second. Before we do that, however, let\u2019s take a few minutes to meditate on the nature of IP addresses. What <I>is<\/I> an IP address? Well, in general, an IP address consists of:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>Anywhere from 1 to 3 digits (the values 0 through 9) followed by a period (e.g., <B>192.<\/B>)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>Anywhere from 1 to 3 digits followed by a second period (e.g., <B>168.<\/B>)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>Anywhere from 1 to 3 digits followed by one more period (e.g., <B>120.<\/B>)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>Anywhere from 1 to 3 digits (e.g., <B>1<\/B>)<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Believe it or not, that\u2019s an awfully good description of our search pattern as well. The construction <B>\\d{1,3}<\/B> means \u201cFind some digits; there must be at least one digit (<B>1<\/B>) but no more than three digits (<B>3<\/B>).\u201d The construction <B>\\.<\/B> Means \u201cFind a dot.\u201d If you follow the pattern all the way through, what search criteria do we end up with? You got it:<\/P>\n<P><B>1 to 3 digits<\/B> (the values 0 through 9) followed by a <B>period<\/B>, then <B>1 to 3 digits<\/B> followed by a <B>second period<\/B>, then <B>1 to 3 digits<\/B> followed by one more period, then <B>1 to 3 final digits<\/B>.<\/P>\n<P>Crazy, huh? But it all works.<\/P>\n<P>After we define the search pattern our next step is to call the <B>Execute<\/B> method and perform a regular expressions search on the file contents; that\u2019s what we do here:<\/P><PRE class=\"codeSample\">Set colMatches = objRegEx.Execute(strSearchString)\n<\/PRE>\n<P>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\u2019s <B>Count<\/B> property is greater than 0:<\/P><PRE class=\"codeSample\">If colMatches.Count &gt; 0 Then\n<\/PRE>\n<P>If the Count property <I>is<\/I> 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 <B>Value<\/B> (that is, the text that met the search pattern):<\/P><PRE class=\"codeSample\">Wscript.Echo strMatch.Value\n<\/PRE>\n<P>What do we get back when we run this script against MJ\u2019s sample dataset? This is what we get back:<\/P><PRE class=\"codeSample\">192.168.120.0\n255.255.255.0\n<\/PRE>\n<P>Don\u2019t want the subnet mask to be included? That\u2019s fine; just add an If Then statement to your For Each loop and filter out any IP addresses that begin with 255. That\u2019s something you can do by using the <B>Left<\/B> function to determine whether or not the first three characters in the value are equal to 255:<\/P><PRE class=\"codeSample\">For Each strMatch in colMatches   \n    If Left(strMatch.Value, 3) &lt;&gt; &#8220;255&#8221; Then \n       Wscript.Echo strMatch.Value\n    End If\nNext\n<\/PRE>\n<P>Run this modified script and you\u2019ll get back the following:<\/P><PRE class=\"codeSample\">192.168.120.0\n<\/PRE>\n<P>Bye-bye subnet mask.<\/P>\n<P>And hello, Barcelona. If you\u2019re planning on attending the IT Forum in Barcelona (November 12-16) <A href=\"mailto:scripter@microsoft.com?subject=Barcelona\"><B>drop us a line<\/B><\/A> 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\u2019d appreciate hearing about those as well. After all, even Scripting Guy Jean Ross has to eat.<\/P>\n<P>Well, once a month, anyway.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,4,14,5],"class_list":["post-63923","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-text-files","tag-vbscript"],"acf":[],"blog_post_summary":"<p>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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63923","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=63923"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63923\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=63923"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=63923"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=63923"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}