User Tools

Site Tools


en:powershell:dns

This is an old revision of the document!


FIXME 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 is the difference between a string and an object.

Initial request

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:

  1. Vérifier les données fournies par le demandeur: la confiance n'exclut jamais le contrôle.
  2. Fournir le rapport preCheck à votre commanditaire.

Pour l'exemple, partons de fichier initial suivant:

A_RecordProvider
google.cap1
google.comp1
google.frp2
google.totop3

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:

dns_v1.ps1
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:

  1. Les résultats s'affichent sur l'écran mais c'est très dur d'en extraire les informations.
  2. nslookup n'est pas une commande Powershell alors on n'obtient pas d'objet adapté à notre requête DNS
  3. 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

dns_v2.ps1
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.

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)
    }   
}

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.

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

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.

NameTypeIPAddressStatus
google.caA172.217.13.131ok
google.comA172.217.13.110ok
google.frA172.217.13.163ok
google.totoAko
en/powershell/dns.1617645176.txt.gz · Last modified: 2021/04/05 13:52 by lonclegr