Parsing nslookup: Only Return the Resolved IP

It was late last Friday evening when a vendor and I worked though some maintenance. As a part of the work (which actually lasted well into the weekend), we needed to remove two DNS A records and replace them with CNAME records. I figured that before the change, I would return the current resolution results, so I would be able to ensure the DNS change took place, after the night’s weekend’s work.

You’re probably familiar with the standard output of nslookup.

PS> nslookup subdomain.mydomain.com
Server:  mydomain.com
Address:  10.10.10.1

Name:    subdomain.mydomain.com
Address:  10.20.30.40

These results indicate the name, subdomain.mydomain.com, resolves to an IP address of 10.20.30.40 when using the mydomain.com nameserver, at 10.10.10.1. I wanted to clean up this output, and since I had time to kill while fighting off sleep, I figured — why not? I started by piping the results of nslookup to the Select-String cmdlet looking for the string, ‘Address.’ As you can see in the example below, it returns both the IP of the server where the resolution took place, and the results. After that, there doesn’t seem to be a way to distinguish one line from the other. I needed another way to only return the results.

PS> nslookup subdomain.mydomain.com | Select-String Address

Address: 10.10.10.1
Address: 10.20.30.40

I decided to pipe the command above to the Get-Member cmdlet to see what kind of object the Select-String cmdlet returned. The property that jumped out at me right away was LineNumber — was it really going to be that easy?

   TypeName: Microsoft.PowerShell.Commands.MatchInfo

Name         MemberType Definition
----         ---------- ----------
Equals       Method     bool Equals(System.Object obj)
GetHashCode  Method     int GetHashCode()
GetType      Method     type GetType()
RelativePath Method     string RelativePath(string directory)
ToString     Method     string ToString(), string ToString(string directory)
Context      Property   Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename     Property   string Filename {get;}
IgnoreCase   Property   bool IgnoreCase {get;set;}
Line         Property   string Line {get;set;}
LineNumber   Property   int LineNumber {get;set;}
Matches      Property   System.Text.RegularExpressions.Match[] Matches {get;set;}
Path         Property   string Path {get;set;}
Pattern      Property   string Pattern {get;set;}

Here’s the thing, the output of nslookup is always the same: this on a this line, and that on that line. This is likely why the LineNumber property looked so promising, so quickly. Now that we know we have this property, let’s try and use it. While my first line number guess worked (read, dumb luck), let’s do it wrong first. Consider again our most recent output below.

PS> nslookup subdomain.mydomain.com | Select-String Address

Address: 10.10.10.1
Address: 10.20.30.40

You might think you would want line 3 of our output, but that’s not correct. Even though Select-String has trimmed down the output, the line numbers are all still intact. Look at the very first example at the top of this post. Line 3 is blank — it’s line 5 that we want! Take a look.

PS> nslookup subdomain.mydomain.com | Select-String Address | Where-Object LineNumber -eq 5

Address: 10.20.30.40

If you want to store this as as a string, use the .ToString() method.

PS> (nslookup subdomain.mydomain.com | Select-String Address | Where-Object LineNumber -eq 5).ToString()
Address: 10.20.30.40

And, if you want to remove the word “address,” the colon, and the space, in order to only return the IP address, then you can parse the string by using the .Split() method. The example below splits the string at the space and return the last element — what’s on the right side of the space.

PS> (nslookup subdomain.mydomain.com | Select-String Address | Where-Object LineNumber -eq 5).ToString().Split(' ')[-1]
10.20.30.40

I hope this was helpful for someone. Until next time.

6 thoughts on “Parsing nslookup: Only Return the Resolved IP

  1. Bear

    Hi! Thank you for you post.
    I have some problem with execute this script on Windows 7 (Powershell version 2.0).

    Where-Object : Cannot bind parameter ‘FilterScript’. Cannot convert the “LineNumber” value of type “System.String” to type “System.Management.Automation.
    ScriptBlock”.
    At line:1 char:57
    + (nslookup $myipv4 | Select-String Address | Where-Object <<<< LineNumber -eq 5).ToString().Split(' ')[-1]
    + CategoryInfo : InvalidArgument: (:) [Where-Object], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.WhereObjectCommand

    Reply
  2. tommymaynard Post author

    The problem here is that I wrote the example for PowerShell 3.0 and greater. In PowerShell 2.0, try this:

    (nslookup subdomain.mydomain.com | Select-String Address | Where-Object {$_.LineNumber -eq 5).ToString().Split(‘ ‘)[-1]}

    The difference here is that in 2.0 you needed curly brackets around the entire value you’re providing to the FilterScript parameter. It’s not necessary, but it should have also included the FilterScript parameter name, such as this complete, 2.0 example does:

    (nslookup subdomain.mydomain.com | Select-String Address | Where-Object -FilterScript {$_.LineNumber -eq 5).ToString().Split(‘ ‘)[-1]}.

    Finally, as you can see in the two above examples, we need to add the $_. in front of the property name, so this: LineNumber becomes this: $_.LineNumber. Hope this helps!

    Reply
  3. Sally

    hi, i am having problems trying to write a script that only returns the name using the iP address 198.111.176.6. and it contains a pipeline using the nslookup, and select-string. the scrip must only emit the name of the host and nothing else.
    i tried, nslookup 198.111.176.6 |select-string displayName
    but nothing came up.
    2. I am suppose to IP address is pass as a parameter to the script, add the syntax as the first line in the script. param ($ipaddress) Alter the pipeline by replacig the hard code IP address with the name of the passed parameter. test the scrip with multiple address.
    any help would be great.

    Reply
    1. tommymaynard Post author

      The command-line tool, nslookup, doesn’t returns objects (properties, methods, etc.). It returns text. This means that to use it the way we want, we may have to parse the text-based output. This is why I use things like Select-String (string: think text). Based on this post and its contents, you can change what Select-String returns. Instead of “Address,” use “Name,” as well as the correct line number (4). The below examples use the -split comparison operator as opposed to the .Split() method used in the post.

      PowerShell 3.0+
      ((nslookup 198.111.176.6 | Select-String Name | Where-Object LineNumber -eq 4).ToString() -split ‘\s+’)[-1]

      PowerShell 2.0-
      ((nslookup 198.111.176.6 | Select-String Name | Where-Object -FilterScript {$_.LineNumber -eq 4}).ToString() -split ‘\s+’)[-1]

      Reply
  4. Morten

    Depending on what you want to do and the Powershell version, alternatives could be:
    “$var = Resolve-DnsName tommymaynard.com ; $var.IPAddress”
    “$var = Test-Connection -Count 1 tommymaynard.com ; $var.IPV4Address.IPAddressToString”

    Reply
  5. Tired Scripter

    Great idea to pipe the output to Get-Member and use LineNumber. I will treasure that knowledge. Thanks much.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *