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.
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
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!
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.
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]
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”
Great idea to pipe the output to Get-Member and use LineNumber. I will treasure that knowledge. Thanks much.