====== DNS ======
Par cet exemple du DNS, je souhaite remontrer la différence entre une chaîne de caractères et un objet.
===== Demande initiale =====
Supposons que vous ayez à faire énormément de modifications DNS à cause d'un fournisseur qui change de serveur. On vous donne une liste d'enregistrements DNS de type A et il faut les modifier. Comme vous avez les bons réflexes, vous vous lancez dans deux opérations:
- Vérifier les données fournies par le demandeur: la confiance n'exclut jamais le contrôle.
- Fournir le rapport preCheck à votre commanditaire.
Pour l'exemple, partons de fichier initial suivant:
A_Record,Provider
google.ca,p1
google.com,p1
google.fr,p2
google.toto,p3
===== Le piège =====
Si on décide d'aborder le défi en utilisant powershell, alors bien des gens seraient tenter de partir ainsi en utilisant nslookup:
Import-Csv -Path input_dns.csv | foreach {
nslookup $_.A_Record 8.8.8.8
}
On obtient des choses horribles.
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
Cela pose les problèmes suivants:
- Les résultats s'affichent sur l'écran mais c'est très dur d'en extraire les informations.
- nslookup n'est pas une commande Powershell alors on n'obtient pas d'objet adapté à notre requête DNS
- Impossible d'utiliser les résultats pour créer notre fichier de preCheck
===== Le bon outil =====
Nous allons donc utiliser la commande DNS PowerShell: Resolve-Dns
Import-Csv -Path input_dns.csv | foreach {
Resolve-DnsName $_.A_Record -Type A -Server 8.8.8.8
}
Cette fois-ci on obtient quelque chose de beaucoup plus sympa avec des objets que nous allons pouvoir manipuler.
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
On obtient toujours une exception pour l'enregistrement qui n'existe pas, mais avec un bloc "try" et une redirection de sortie d'erreurs, on va s'en sortir.
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)
}
}
On obtient des objets que nous allons pouvoir manipuler et exporter.
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
===== Script final =====
On se rappelle ce que l'on souhaite: prendre tous les enregistrements DNS A demandés et s'assurer qu'il n'y a pas d'erreurs dans la demande du client.
$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
Le résultat permet de mettre en valeur un domaine qui n'a pas d'entrée A connue. C'est ce que l'on souhaitait découvrir.
"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"