This is an old revision of the document!
Table of Contents
This page is not fully translated, yet. Please help completing the translation.
(remove this paragraph once the translation is finished)
DNS
Here I want to show how huge the difference is between a string and an object.
Initial request
To start, let's suppose you have to perform a lot of DNS modifications because a service provider of yours has changed IP server. Since you are wise, you are going to follow the rule: Trust but verify.
- Check input: maybe some mistakes in the request
- Provide a preCheck report to the requester
This is the example we are going to deal with:
A_Record | Provider |
---|---|
google.ca | p1 |
google.com | p1 |
google.fr | p2 |
google.toto | p3 |
Trap to avoid
Sysadmins are used to execute nslookup command to query DNS servers. Let's put it into a powershell script.
- dns_v1.ps1
Import-Csv -Path input_dns.csv | foreach { nslookup $_.A_Record 8.8.8.8 }
Output is a nightmare.
nslookup : Non-authoritative answer: At line:1 char:1 + nslookup google.ca 8.8.8.8 + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (Non-authoritative answer::String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError Server: dns.google Address: 8.8.8.8 Name: google.ca Addresses: 2607:f8b0:4020:805::2003 172.217.13.131
Here is an issues list:
- Quite difficult to parse results
- nslookup is not a built-in Powershell command, as a result we don't get answer as kind of DNS object
- Really hard to create preCheck output file
the right tool for the right problem
Recent versions of PowerShell includes the perfect command for this request: Resolve-Dns.
- dns_v2.ps1
Import-Csv -Path input_dns.csv | foreach { Resolve-DnsName $_.A_Record -Type A -Server 8.8.8.8 }
Now script outputs something we can easily manage and export.
Name Type TTL Section IPAddress ---- ---- --- ------- --------- google.ca A 49 Answer 172.217.13.131 google.com A 299 Answer 172.217.13.110 google.fr A 299 Answer 172.217.13.163 Resolve-DnsName : google.toto : DNS name does not exist At line:2 char:7 + Resolve-DnsName $_.A_Record -Type A -Server 8.8.8.8 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ResourceUnavailable: (google.toto:String) [Resolve-DnsName], Win32Exception + FullyQualifiedErrorId : DNS_ERROR_RCODE_NAME_ERROR,Microsoft.DnsClient.Commands.ResolveDnsName
We still raise an exception from google.toto record. We are going to use a try-catch block to handle this.
- dns_v3.ps1
Import-Csv -Path input_dns.csv | foreach { $currentLine = $_ $record = $currentLine.A_Record try { $result = Resolve-DnsName $record -Type A -Server 8.8.8.8 2> $null Write-Host $result.getType().fullname } catch { Write-Host ("Error with record: {0}" -f $record) } }
When the DNS A record exists, we get an object from Microsoft.DnsClient.Commands.DnsRecord_A class. Otherwise we catch the exception properly.
Microsoft.DnsClient.Commands.DnsRecord_A Microsoft.DnsClient.Commands.DnsRecord_A Microsoft.DnsClient.Commands.DnsRecord_A Error with record: google.toto Name Type TTL Section IPAddress ---- ---- --- ------- --------- google.ca A 299 Answer 172.217.13.131 google.com A 299 Answer 172.217.13.110 google.fr A 299 Answer 172.217.13.163
Final script
Reminder: we want to verify if all DNS A records provided by the requester are correct.
- dns_final.ps1
$results = @() Import-Csv -Path input_dns.csv | foreach { $currentLine = $_ $record = $currentLine.A_Record try { $result = Resolve-DnsName $record -Type A -Server 8.8.8.8 2> $null Write-Host $result.getType().fullname $exportLine = $result | Select-Object -Property Name,Type,IPAddress $exportLine | Add-Member -MemberType NoteProperty -Name "Status" -Value "ok" } catch { Write-Host ("Error with record: {0}" -f $record) $exportLine = New-Object psobject -Property @{ 'Name' = $record; 'Type' = 'A'; 'IPAddress' = ''; 'Status' = 'ko'; } } $results += $exportLine } $results | Export-Csv -Path dnsPreCheck.csv -Delimiter "," -Encoding UTF8 -NoTypeInformation
From the result we can easily identify names without DNS A records. Mission accomplished
Name | Type | IPAddress | Status |
---|---|---|---|
google.ca | A | 172.217.13.131 | ok |
google.com | A | 172.217.13.110 | ok |
google.fr | A | 172.217.13.163 | ok |
google.toto | A | ko |