Replace NSLookup with a Built-in Windows 8 PowerShell Function

Replace NSLookup with a Built-in Windows 8 PowerShell Function

  • Comments 7
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, continues his discussion about using Windows PowerShell on Windows 8 to troubleshoot DNS issues.

Microsoft Scripting Guy, Ed Wilson, is here. Yesterday, I talked about using some of the functions from the DNSClient module to troubleshoot networking issues. Specifically, I talked about looking at the configured DNS server and at the DNS client cache.

Today, I want to continue that discussion by examining a couple of more functions.

Resolving DNS names

To make a connection, I need to resolve a DNS host name to an IP address. Actually, I do not need to do this; my computer needs to do this. But if the name does not resolve correctly, then my applications do not work. Often, when traveling, a quick call to the Help desk turns into a very long and frustrating call to the Help desk, which in turn becomes the Helpless desk. Dude!

Therefore, I need to do all the troubleshooting on my own, so I can tell the Help desk what they need to do in order to resolve my problem. An intermediate troubleshooting step is to use the old-fashioned NSLookup utility. A long time ago, I used to have a dedicated NSLookup GUI utility. But that was a long time ago. When I moved into consulting and began working on different systems, I decided I needed to learn how to use the Windows NSLookup command-line utility—because it was the only tool I could be confident would be available. Unfortunately, the old-fashioned Windows NSLookup command-line utility is not all that much fun to use.

The PowerShell “NSLookup” tool

Luckily, I no longer have to use the old-fashioned command-line NSLookup tool because Windows 8, Windows Server 2012, and even the Microsoft Surface have the DNSClient module built-in. This module supplies the Resolve-DNSName. This function works great (despite the fact that some in the community believe it should have been named Get-DNSName).

In its most basic form, I simply type the host to resolve as an argument for Resolve-DNSName. This technique is shown here.

Resolve-DnsName www.scriptingguys.com

The command and its associated output is shown here.

14:28 C:\> Resolve-DnsName www.scriptingguys.com

 Name                           Type   TTL   Section    NameHost

----                           ----   ---   -------    --------

www.scriptingguys.com          CNAME  3600  Answer     scriptingguys.com

 Name       : scriptingguys.com

QueryType  : A

TTL        : 3600

Section    : Answer

IP4Address : 64.4.11.37

  

Name       : scriptingguys.com

QueryType  : A

TTL        : 3600

Section    : Answer

IP4Address : 65.55.58.201

 

Name                   : scriptingguys.com

QueryType              : SOA

TTL                    : 3600

Section                : Authority

NameAdministrator      : msnhst.microsoft.com

SerialNumber           : 2012050301

TimeToZoneRefresh      : 1800

TimeToZoneFailureRetry : 900

TimeToExpiration       : 2419200

DefaultTTL             : 3600

 

The thing that is a bit interesting here is that there are three different object returned by this query. The objects are shown here.

14:30 C:\> Resolve-DnsName www.scriptingguys.com | gm -MemberType Properties | select

 typename -Unique

 TypeName

--------

Microsoft.DnsClient.Commands.DnsRecord_PTR

Microsoft.DnsClient.Commands.DnsRecord_A

Microsoft.DnsClient.Commands.DnsRecord_SOA

 

If I am interested in a specific record type, I query it directly by specifying the type parameter, as shown here.

14:34 C:\> Resolve-DnsName www.scriptingguys.com -Type ptr

 

Name                           Type   TTL   Section    NameHost

----                           ----   ---   -------    --------

www.scriptingguys.com          CNAME  3251  Answer     scriptingguys.com

 

Name                   : scriptingguys.com

QueryType              : SOA

TTL                    : 3251

Section                : Authority

NameAdministrator      : msnhst.microsoft.com

SerialNumber           : 2012050301

TimeToZoneRefresh      : 1800

TimeToZoneFailureRetry : 900

TimeToExpiration       : 2419200

DefaultTTL             : 3600

 Unfortunately, the type parameter does not accept multiple types. It does not generate an error, but it leads to unpredictable results. If I need to examine multiple record types I type the record types as an array and send them down the pipeline through the Foreach-Object cmdlet. This technique is shown here.

"ptr", "a" | % {Resolve-DnsName -Name www.scriptingguys.com -Type $_}

 I can use the same technique to look up multiple DNS names. This technique appears here where I return only the CNAME records for www.microsoft.com and ftp.microsoft.com.

 "www.microsoft.com", "ftp.microsoft.com" | % {Resolve-DnsName $_ -type cname}

 If I want to check the DNS Cache for a specific record, I can query it directly by using the Resolve-DNSName function. If a record does not exist in cache (perhaps it timed out), an error returns, as shown here.

14:41 C:\> Resolve-DnsName ftp.microsoft.com -CacheOnly

Resolve-DnsName : ftp.microsoft.com : DNS record does not exist

At line:1 char:1

+ Resolve-DnsName ftp.microsoft.com -CacheOnly

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (ftp.microsoft.com:String) [Reso

   lve-DnsName], Win32Exception

    + FullyQualifiedErrorId : RECORD_DOES_NOT_EXIST,Microsoft.DnsClient.Commands.Re

   solveDnsName

 To see what my DNS server returns, I can query it directly. To do this, I have several options. For example, I can simply specify that I want to use the DNS protocol, as shown here.

Resolve-DnsName ftp.microsoft.com –DnsOnly

If, on the other hand, the problem appears to be intermittent DNS resolution, I may want to specify a specific DNS server. First, I probably need to see how my currently configured DNS servers are set. I use the Get-DNSClientServerAddress function, as shown here.

14:45 C:\> Get-DnsClientServerAddress

InterfaceAlias               Interface Address ServerAddresses

--------------               --------- ------- ---------------

Local Area Connection* 14           33 IPv4    {}

Local Area Connection* 14           33 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::...

vEthernet (WirelessSwitch)          31 IPv4    {192.168.6.1, 64.134.255.2, 64.134...

vEthernet (WirelessSwitch)          31 IPv6    {}

isatap.owv.atl.wayport.net          44 IPv4    {192.168.6.1, 64.134.255.2, 64.134...

isatap.owv.atl.wayport.net          44 IPv6    {}

Local Area Connection* 12           25 IPv4    {}

Local Area Connection* 12           25 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::...

vEthernet (InternalSwitch)          19 IPv4    {192.168.3.100}

vEthernet (InternalSwitch)          19 IPv6    {}

isatap.{FC2087E9-6988-45E...        40 IPv4    {192.168.3.100}

isatap.{FC2087E9-6988-45E...        40 IPv6    {}

Loopback Pseudo-Interface 1          1 IPv4    {}

Loopback Pseudo-Interface 1          1 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::...

Teredo Tunneling Pseudo-I...        34 IPv4    {}

Teredo Tunneling Pseudo-I...        34 IPv6    {}

6TO4 Adapter                        39 IPv4    {}

6TO4 Adapter                        39 IPv6    {}

I can easily clean up the output by filtering only the entries that contain server addresses. This is shown here.

14:46 C:\> Get-DnsClientServerAddress | ? serveraddresses

InterfaceAlias               Interface Address ServerAddresses

--------------               --------- ------- ---------------

Local Area Connection* 14           33 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::...

vEthernet (WirelessSwitch)          31 IPv4    {192.168.6.1, 64.134.255.2, 64.134...

isatap.owv.atl.wayport.net          44 IPv4    {192.168.6.1, 64.134.255.2, 64.134...

Local Area Connection* 12           25 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::...

vEthernet (InternalSwitch)          19 IPv4    {192.168.3.100}

isatap.{FC2087E9-6988-45E...        40 IPv4    {192.168.3.100}

Loopback Pseudo-Interface 1          1 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::...

After I have my listing of DNS servers, I can check them one at a time. I do this by specifying the DnsServer parameter and specifying that I want to use DNS, as shown here.

Resolve-DnsName www.msn.com -DnsOnly -Server 192.168.6.1

I do not have to specify an IP address for the DNS Server. For example, I can query the DNS server by host name. This technique is shown here.

Resolve-DnsName www.msn.com -Server ns1.msft.net

If I determine I have a polluted DNS cache, I use Windows PowerShell to clear the cache. The command is shown here.

Clear-DnsClientCache

Join me tomorrow when I will have the third article of Microsoft MVP Richard Siddaway’s Windows PowerShell workflow basics series. You can review the second and the first articles in that series on the Hey, Scripting Guy! Blog post.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Dude!  I had no idea about this cmdlet, one of my new favorites!  Thanks for what you do and sharing with the community!

  • @Brian Wilhite Dude, with 2,000 built in cmdlets and function on Windows 8, it is very hard to know exactly every single one of them. Actually, what I do on a weekly  basis is use Get-Command and browse through the available functions and cmdlets, and then spend some time playing with them. Yes, this cmdlet is one of my favorites as well. It rocks, and I can use PowerShell to parse the output.

  • Is this/will be available on windows 7 and 2008 server R2?

  • @Dalmiro: This is not supported I'm sure, but you can do this:

    1. Ensure your Windows 7/2008 R2 machine has WMF 3.0 (PowerShell 3.0) installed.

    2. Copy the "DnsClient" modules folder from a Windows 8/2012 machine to the modules folder on your Windows 7/2008 R2 machine.

    The default path to the modules folder is:

    C:\windows\system32\windowspowershell\v1.0\Modules

    With the limited tested I did, it works just fine.

  • This is a nice cmdlet, unfortunately it isn't as robust as nslookup. It can't handle a referral from a root server, for example:

    Resolve-DnsName com. -Type NS -DnsOnly -NoRecursion -Server a.root-servers.net

    I assume it's because it only looks at the answer section, which is empty in a referral. Still, would be useful if I could use it in a script that emulates a recursive DNS resolver by starting at the root, etc.