DNS Zone Information CSV collector

This script takes command line arguments of a remote dns server, uses dnscmd to collect all the zones and some extended information about them and outputs to a csv file with the name of the remote server. You can input multiple remote servers. I have only tested this with windows 2003 server, if 2008 dnscmd output is the same format it should work as well. I wrote this to collect information on scavenging settings, so the output is more focused on that. You will need to know what the numeric values of the /zoneinfo results mean in order to interpret the csv file output.

Script Code (Perl)

#dns zone enumeration and detail gathering

#run the command with arguments of the dns servers hosting the zones. This script enumerates

#all zones, collects some of the extended details and outputs to CSV format. Requires dnscmd.exe and

#appropriate rights on the remote machine

foreach (@ARGV) {

my $filename = $_ . “.csv”;

open OUTFILE, “>$filename”

die “Can’t open output file\n”;

print OUTFILE “Zone Name,Type,Storage,Updates,DS Integrated,Aging On,Refresh Aging,No Refresh Aging,Scavenge Available\n”;

my $dnsserver = $_;

$output = `dnscmd $dnsserver /enumzones`;

@outputarr = split(/\n/,$output);

$beginning = 0;

foreach (@outputarr) {

if (!($beginning)) {

if ($_ =~ /Zone name/) {

$beginning = 1;


} else {


$_ =~ s/^\s//;

my @temparr = split(/\s+/,$_);

if ($temparr[0] =~ /\./) {

#proper zone found,

#Format: Name, Type, Storage, Properties(multiple)

# properties Secure Rev Aging

my $details = getdetail($dnsserver,$temparr[0]);

my $outline = “$temparr[0],$temparr[1],$temparr[2],$details”;

print OUTFILE $outline;



} #end of all output from enumzones

close OUTFILE;

} #end foreach server’s passed as args

sub getdetail {

my ($dnsserver,$zone) = @_;

my $zoneinfo = `dnscmd $dnsserver /zoneinfo $zone`;

my @zonedetails = split(/\n/,$zoneinfo);

my ($zoneupdate, $dsintegrated, $aging, $agerefresh, $age_no_refresh, $scavenge_avail) = “”;

foreach (@zonedetails) {

my $line = $_;

if ($line =~ /update/) {

$zoneupdate = parsevalue($line);

} elsif ($line =~ /aging/) {

$aging = parsevalue($line);

} elsif ($line =~ /DS integrated/) {

$dsintegrated = parsevalue($line);

} elsif ($line =~ /refresh interval/) {

$agerefresh = parsevalue($line);

} elsif ($line =~ /no refresh/) {

$age_no_refresh = parsevalue($line);

} elsif ($line =~ /scavenge available/) {

$scavenge_avail = parsevalue($line);


} #end details

my $retval = “$zoneupdate,$dsintegrated,$aging,$agerefresh,$age_no_refresh,$scavenge_avail\n”;

return $retval;


sub parsevalue {

my $val = @_[0];

my @temparr = split(/=/, $val);

$val = $temparr[1];

$val =~ s/ //g;

chomp $val;

return $val;