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 typeparameter, 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 typeparameter 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