J’ai développé un (plutôt deux, à vrai dire) script(s) Powershell permettant de remplacer la fonction de filtre présente sur la console DNS. En effet, celle-ci est un peu pénible à utiliser car il faut attendre que toute la zone soit chargée dans la console si le filtre n’est pas encore actif, puis il faut rafraîchir… et il est persistant après fermeture, ce qui fait qu’il faut réinitialiser le filtre et actualiser lorsqu’on souhaite revenir à une vision d’ensemble.
A l’exécution, le script demande le nom ou l’IP du serveur DNS à interroger, ainsi que la chaîne de caractères à trouver dans le nom de l’enregistrement. Le joker * est utilisable, ce qui permet à la fois de rechercher une expression ou une chaîne stricte.
La version basique du script renvoie ses résultats dans la console avec uniquement le nom de l’enregistrement :
Write-Host "=========================================="
Write-Host "DNS records listing script - Basic Version"
Write-Host "=========================================="
$dnsnode = Read-Host "DNS Server to query"
$lfseq = Read-Host "Character sequence to look for ('*' tokens accepted)"
Write-Host "Connecting to DNS Server and retrieving DNS zones"
$dnszones = Get-DNSServerZone -ComputerName $dnsnode | Where-Object {$_.IsReverseLookupZone -eq $false}
foreach($dnszone in $dnszones){
Write-Host "Zone currently parsed:" $dnszone.ZoneName
$dnsrecords = Get-DnsServerResourceRecord -ComputerName $dnsnode -ZoneName $dnszone.ZoneName | Where-Object {$_.HostName -like "$lfseq"} | ft HostName
if($dnsrecords.length -gt 0) { $dnsrecords }
else { Write-Host "No matching records found." }
Write-Host "`r"
}
Write-Host "Parsing over."
Write-Host "Bye."
La version améliorée renvoie les résultats dans la console, mais génère un fichier CSV offrant plus d’informations (type d’enregistrement et données de l’enregistrement) et effectue une suppression des doublons : nécessaire car la commande Powershell peut renvoyer plusieurs fois le même enregistrement si il est dans une sous-zone. Par exemple, en considérant la zone infra.local, si un enregistrement s’appelle sql dans la sous-zone prod, il apparaîtra alors deux fois : une fois en tant que sql.prod et une fois en tant que sql.prod.infra.local.
Write-Host "============================================="
Write-Host "DNS records listing script - Enhanced Version"
Write-Host "============================================="
$dnsnode = Read-Host "DNS Server to query"
$lfseq = Read-Host "Character sequence to look for ('*' tokens accepted)"
$today = Get-Date -f yyyyMMdd
$path = "dns-$today.csv"
$csvheader = "Hostname,Zone,RecordType,RecordData"
Add-Content -Value $csvheader -Path $path
Write-Host "Connecting to DNS Server and retrieving DNS zones"
$dnszones = Get-DNSServerZone -ComputerName $dnsnode | Where-Object {$_.IsReverseLookupZone -eq $false}
foreach($dnszone in $dnszones){
Write-Host "Zone currently parsed:" $dnszone.ZoneName
$dnsrecords = Get-DnsServerResourceRecord -ComputerName $dnsnode -ZoneName $dnszone.ZoneName | Where-Object {$_.HostName -like "$lfseq"}
if($dnsrecords.length -gt 0){
foreach($dnsrecord in $dnsrecords){
Write-Host "Record: "$dnsrecord.Hostname
switch($dnsrecord.RecordType){
"A" {$recorddata = $dnsrecord.RecordData.IPv4Address.IpAddressToString}
"CNAME" {$recorddata = $dnsrecord.RecordData.HostNameAlias}
}
if($dnsrecord.HostName.SubString($dnsrecord.HostName.Length-$dnszone.ZoneName.Length,$dnszone.ZoneName.Length) -ne $dnszone.ZoneName) {
$row = $dnsrecord.Hostname+","+$dnszone.ZoneName+","+$dnsrecord.RecordType+","+$recorddata
Add-Content -Value $row -Path $path
}
}
Write-Host "DNS records found:"$dnsrecords.length
}
else { Write-Host "No matching records found." }
Write-Host "`r"
}
Write-Host "Parsing over, cleaned duplicates, hence the difference between the number of lines in the CSV file and the number displayed in console. Please find the output CSV file named $path in $pwd."
Write-Host "Bye."
explorer $pwd