I was watching the TechEd video
The Network Files, Case #53: Diagnosing Diseases of DNS and began thinking about an easy way to troubleshoot local DNS client cache. The first command that came to mind was 'IPConfig /DisplayDNS', but it is a hassle to scroll through all of the output looking for what I wanted. I ended up writing a short script to convert the results into a Powershell object that I could then work with easily.
Function Get-DNSClientCache{
$DNSCache = @()
Invoke-Expression "IPConfig /DisplayDNS" |
Select-String -Pattern "Record Name" -Context 0,5 |
%{
$Record = New-Object PSObject -Property @{
Name=($_.Line -Split ":")[1]
Type=($_.Context.PostContext[0] -Split ":")[1]
TTL=($_.Context.PostContext[1] -Split ":")[1]
Length=($_.Context.PostContext[2] -Split ":")[1]
Section=($_.Context.PostContext[3] -Split ":")[1]
HostRecord=($_.Context.PostContext[4] -Split ":")[1]
}
$DNSCache +=$Record
}
return $DNSCache
}
The script begins by invoking the IPConfig command that we all know and love. A typical DNS record looks similar to the one below.
Invoke-Expression "IPConfig /DisplayDNS" |
docs.google.com
----------------------------------------
Record Name . . . . . : docs.google.com
Record Type . . . . . : 1
Time To Live . . . . : 78138
Data Length . . . . . : 4
Section . . . . . . . : Answer
A (Host) Record . . . : 74.125.226.98
Now that we have the information that we want, we need to weed out extraneous lines. The first item that I wanted to capture was the record name. The results of the Invoke-Expression are piped to the Select-String cmdlet with a pattern of "Record Name" and a context of '0,5'. This command searches every line from the pipeline that matches the pattern, then shows zero lines before the match and five afterwards.
Select-String -Pattern "Record Name" -Context 0,5 |
> Record Name . . . . . : docs.google.com
Record Type . . . . . : 1
Time To Live . . . . : 80174
Data Length . . . . . : 4
Section . . . . . . . : Answer
A (Host) Record . . . : 74.125.226.98
We now have a group of objects from the pipeline with the information that we want, we can loop through them and create some Powershell objects. This is done with the use of the ForEach (%) alias, New-Object PSObject and property splatting. For the record name property, I can take the match of the Select-String, split it between the colon and set the property 'Name' to the item after the colon. For the rest of the properties, the script has to pull the information from the postcontext of the match, which is then split and the property assigned to the items after the colon.
%{
$Record = New-Object PSObject -Property @{
Name=($_.Line -Split ":")[1]
Type=($_.Context.PostContext[0] -Split ":")[1]
TTL=($_.Context.PostContext[1] -Split ":")[1]
Length=($_.Context.PostContext[2] -Split ":")[1]
Section=($_.Context.PostContext[3] -Split ":")[1]
HostRecord=($_.Context.PostContext[4] -Split ":")[1]
}
$DNSCache +=$Record
}
Once each of the objects is created, it is added to the $DNSCache array that we created on the first line of the function. The function then returns that array as a Powershell object that can be filtered, sorted and otherwise modified.
return $DNSCache
An example that could be used is shown below.
Get-DNSClientCache | Sort Name | Format-Table Name,TTL,HostRecord -Autosize
As I believe most Powershell users can attest in regards to work, "I've got 99 problems, but Powershell's not one."