I need to parse a windows dns zone file to convert it in another format.
I use Powershell and need to extract values. Here is an example of what the file look like:
;
; Zone NS records
;
@ NS servweb.test.com.
servweb.test.com. A 31.233.196.98
@ NS servweb3.test.com.
servweb3.test.com. A 91.133.157.25
;
; Zone records
;
@ A 85.233.152.58
@ MX 10 mail.factory.com.
@ MX 20 mx2.factory.com.
@ MX 50 servmail3.test.fr.
@ TXT ( "v=spf1 include:spf.sendinblue.com mx ~all" )
@ TXT ( "MS=ms94956023" )
_dmarc TXT ( "v=DMARC1; p=none; sp=none; rua=mailto:[email protected]!10m; ruf=mailto:[email protected]!10m; rf=afrf; pct=100; ri=86400" )
mail._domainkey TXT ( "k=rsa;p=MIGfMA0GCSqNADCBiQKBgQDeMVIzrCa3T14JsNY0viLQBwXsa7shBD6TrBkswsFUToPyMRWC9tbR/5ey0nRBH0ZVxp+lsmTxid2Y2z+FApQ6raISgXE" )
_autodiscover._tcp SRV 0 0 443 owa.factory.com.
_sipfederationtls._tcp SRV 100 1 5061 sipfed.online.lync.com.
_sip._tls SRV 100 1 443 sipdir.online.lync.com.
appli A 193.233.140.115
cpanel A 85.33.152.58
cpcalendars A 85.33.152.58
cpcontacts A 85.33.152.58
ftp CNAME factory.com.
lyncdiscover CNAME webdir.online.lync.com.
mail A 90.115.33.93
I think I can use capture groups to extract values and use it to build my file but I’m stuck…
I tried (S+)s+([A-Za-zs]+)[ t](?=d+)
but it breaks after a few lines.
If you have any clue you’ll be welcome 🙂
Edit: I found a quick and dirty way that fit my need but I’m sure it can be improve 🙂
$domains = Import-Csv -Path C:tempexport_domaines_termines.csv -Delimiter ";"
foreach ($domain in $domains){
$ndd = $domain.Name
$nomfichier = "$ndd.dns"
$records = get-content -Path "C:tempdnsdns$nomfichier" | Where-Object { $_ -notmatch '^;' -and $_.trim() -ne "" } | Select-Object -Skip 10
$fichiergandi = New-Item -Path "C:tempdns$nomfichier.txt" -ItemType File -Force -Confirm:$false
foreach ($record in $records){
$type = $prio = $value = $donnees = $name = $null
$match = Select-String '(S+)s+([A-Za-zs]+)[ t](S+)' -InputObject $record
$type = $match.matches.groups[2].value
if ($type -like "MX") {
$match = Select-String '(S+)s+([A-Za-zs]+)[ t](S+)[ t](S+)' -InputObject $record
$name = $match.matches.groups[1].value
$prio = $match.matches.groups[3].value
$MX = $match.matches.groups[4].value
"$name 10800 IN $type $prio $MX" | Out-File -FilePath $fichiergandi -Append
}
elseif ($type -like "TXT") {
$match = Select-String '(S+)s+([A-Za-zs]+)[ t](S+)[ t](([^)]+))' -InputObject $record
$name = $match.matches.groups[1].value
$donnees = ($match.matches.groups[4].value).Trim()
"$name 10800 IN $type $donnees" | Out-File -FilePath $fichiergandi -Append
}
elseif ($type -like "SRV") {
$match = Select-String '(S+)s+([A-Za-zs]+)[ t](S+)s(S+)s(S+)s(S+)' -InputObject $record
$name = $match.matches.groups[1].value
$prio = $match.matches.groups[3].value
$poids = $match.matches.groups[4].value
$port = $match.matches.groups[5].value
$cible = $match.matches.groups[6].value
"$name 10800 IN $type $prio $poids $port $cible" | Out-File -FilePath $fichiergandi -Append
}
else {
$name = $match.matches.groups[1].value
$donnees = $match.matches.groups[3].value
"$name 10800 IN $type $donnees" | Out-File -FilePath $fichiergandi -Append
}
}
}
2
Answers
Your solution seems more optimized, I need to extract all records and build a file to import in another dns software. The format of the file need to be :
Each record need to be separated by one space. I think special records like TXT or SRV need to be processed differently for example remove parenthesis but I will try to use your base. If you have a little time to comment your code it will definitively help. Thank you.
I would use a switch statement to process the file line by line. Here is my guess at what would be a useful output.
Here is the sample output