PowerShell script to check DNS for domains

Soldato
Joined
25 Mar 2004
Posts
16,007
Location
Fareham
Hi all,

I'm in the middle of writing a PowerShell script that checks a list of domains and sees if the domain exists in DNS, whether it has a valid www.domain.com record, a valid MX record, and whether the website on the domain responds to HTTP requests.

I'm most of the way through it now, but I am wondering if I am doing this in the best way, or if there is a better way to achieve what I want to do.

Essentially I am leveraging nslookup to get the DNS records, but I then have to resort to parsing the values for text strings (which I don't like doing - unexpected results can throw it off). For the website checks I am utilising the System.Net.WebRequest .NET class to check the website responds which seems to work well.

Is there a better way to check the DNS records for all of these domains than throwing queries into nslookup? I find catching exceptions not very good in nslookup for exampe as it's not built into PowerShell.

This is my script so far, takes input domain list from C:\temp\domains.txt, all domains are in the format www.domain.com in the text file:

Code:
#Uses NSLookup to get DNS results based on parameters
Function Get-DNSRecords
{
	param
	(
		$DomainName,
		$RecordType,
		$Server
	)
	
	$DNSRecordCommand = "nslookup -querytype=$RecordType -timeout=10 $DomainName $Server"
	
	Write-Host -ForeGroundColor "Magenta" $DNSRecordCommand
	
	$DNSRecords = Invoke-Expression $DNSRecordCommand
	
	return $DNSRecords
}

#Parse WWW Records
Function Parse-WWWRecords
{
	param
	(
		$DNSRecord
	)

	[array]$ARecords = $Null
	
	for ($i = 0; $i -lt $DNSRecord.Count; $i++)
	{
		if ($DNSRecord[$i] -match "Name")
		{
			$ARecords += ($DNSRecord[($i + 1)]).Split(" ")[-1]
		}
	}
	
	if ($ARecords -ne $Null)
	{
		return $ARecords -Join " ; "
	}
	else
	{
		return $Null
	}
}

#Parse NS Records
Function Parse-NSRecords
{
	param
	(
		$DNSRecord
	)

	[array]$NSRecords = $Null
	
	for ($i = 0; $i -lt $DNSRecord.Count; $i++)
	{
		if ($DNSRecord[$i] -match "nameserver")
		{
			$NSRecords += ($DNSRecord[($i)]).Split(" = ")[-1]
		}
	}
	
	if ($NSRecords -ne $Null)
	{
		return $NSRecords -Join " ; "
	}
	else
	{
		return $Null
	}
}

#Parse MX Records
Function Parse-MXRecords
{
	param
	(
		$DNSRecord
	)
	
	$DNSRecord = $DomainMX

	[array]$MXRecords = $Null
	
	for ($i = 0; $i -lt $DNSRecord.Count; $i++)
	{
		if ($DNSRecord[$i] -match "mail exchanger")
		{
			$MXRecords += ($DNSRecord[($i)]).Split(" = ")[-1]
		}
	}
	
	if ($MXRecords -ne $Null)
	{
		return $MXRecords -Join " ; "
	}
}

#Checks if Website exists
Function Get-HTTPResponse
{
	param
	(
		$URL,
		$TimeOut
	)
	
	Write-Host -ForeGroundColor "Magenta" $URL
	
	$WebRequest = [System.Net.WebRequest]::Create($URL)
	$WebRequest.TimeOut = $TimeOut
	
	Try
	{
		#Attempt this
		$WebResponse = $WebRequest.GetResponse()
	}
	Catch [Exception]
	{
		#Output Exception if any occurs
		Write-Host $($_.Exception)
		
		return ([string]$Error[0].FullyQualifiedErrorId + " - " + [string]$Error[0])
	}
	Finally
	{
		#Close connection if one has been opened
		if ($WebResponse -ne $Null)
		{
			$WebResponse.Close()
		}
	}
	
	if ($WebResponse.StatusCode -eq "OK")
	{
		Write-Host "Domain Reachable"
		return $True
	}
	else
	{
		Write-Host "Domain Unreachable"
		return $False
	}
}

$MasterArray = @()
$Count = 0

$Server = "8.8.8.8"

[array]$Domains = gc "C:\temp\domains.txt"

foreach ($Domain in $Domains)
{
	$Count++

	Write-Host -ForeGroundColor "Yellow" "$Domain #$Count"

	$TempArray = @()
	$TempArray = "" | Select DomainName, PrimaryNS, MXRecord, WWWRecord, WebsiteResponds
	
	[array]$DomainNS = Get-DNSRecords ($Domain.Replace("www.","") + ".") "NS" $Server
	
	$DomainNS | Out-Host
	
	[array]$DomainWWW = Get-DNSRecords ($Domain + ".") "A" $Server
	
	$DomainWWW | Out-Host
	
	[array]$DomainMX = Get-DNSRecords ($Domain.Replace("www.","") + ".") "MX" $Server
	
	$DomainMX | Out-Host
	
	$TempArray.DomainName = ($Domain.Replace("www.",""))
	$TempArray.PrimaryNS = Parse-NSRecords $DomainNS
	$TempArray.MXRecord = Parse-MXRecords $DomainMX
	$TempArray.WWWRecord = Parse-WWWRecords $DomainWWW
	
	#If domain has a WWW record then check if url responds to HTTP response
	if ($TempArray.WWWRecord -ne $Null)
	{
		$TempArray.WebsiteResponds = Get-HTTPResponse "http://$Domain" 20000
	}
	
	$MasterArray += $TempArray
}

$MasterArray | ft
 
Guess I may have been speaking over people's heads as I got no replies, as is typical with these things after some investigation I fixed this myself. I used the .exe found at http://www.codeproject.com/KB/IP/DNS_NET_Resolver.aspx as my assembly and then called this for my DNS queries.

This is my final script version, I am simply returning NS Servers, WWW. AName records, and the MX records for each domain in the list so the script is geared for that. I am also checking if the WWW.domain.com responds to an HttpWebRequest and recording if it does or not.

Code:
#Gets DNS records
Function Get-DNS
{
	param
	(
		$DomainName,
		$RecordType,
		$Server
	)
	
	#Set Record Class based on input Record Type
	Switch ($RecordType)
	{
		AName {[Heijden.DNS.QType]$RecordClass = 1} #AName Record
		NS {[Heijden.DNS.QType]$RecordClass = 2} #NS Record
		MX {[Heijden.DNS.QType]$RecordClass = 15} #MX Record
		default {[Heijden.DNS.QType]$RecordClass = 255} #ANY
	}
	
	#Add new DNS Resolver Object using specific DNS Server
	$Resolver = New-Object Heijden.DNS.Resolver($Server)
	
	#Set Record Type
	#[Heijden.DNS.QType]$RecordClass = $RecordNumber
	
	#Perform DNS Query
	$DNSResults = [Heijden.DNS.Response]$Resolver.Query($DomainName, $RecordClass)
	
	#Holds Response
	[array]$Response = $Null
	
	#Process Results based on input Record Type
	Switch ($RecordType)
	{
		AName
		{
			#Check if one or more AName Records returned
			if ($DNSResults.RecordsA.Count -gt 0)
			{
				#Loop through AName Records
				for ($i = 0; $i -lt $DNSResults.RecordsA.Count; $i++)
				{
					$Response += $DNSResults.RecordsA[$i].Address.ToString()
				}
			}
		}
		NS
		{
			#Check if one or more NS Records returned
			if ($DNSResults.RecordsNS.Count -gt 0)
			{
				#Loop through NS Records
				for ($i = 0; $i -lt $DNSResults.RecordsNS.Count; $i++)
				{
					$Response += $DNSResults.RecordsNS[$i].NSDNAME.ToString()
				}
			}
		}
		MX
		{
			#Check if one or more MX Records returned
			if ($DNSResults.RecordsMX.Count -gt 0)
			{
				#Loop through MX Records
				for ($i = 0; $i -lt $DNSResults.RecordsMX.Count; $i++)
				{
					$Response += $DNSResults.RecordsMX[$i].PREFERENCE.ToString() + ":" + $DNSResults.RecordsMX[$i].EXCHANGE.ToString()
				}
			}
		}
	}
	
	if ($Response -ne $Null)
	{
		return $Response -Join " ; "
	}
	else
	{
		return $Null
	}
}

#Checks if Website exists
Function Get-HTTPResponse
{
	param
	(
		$URL,
		$TimeOut
	)
	
	Write-Host -ForeGroundColor "Magenta" $URL
	
	$WebRequest = [System.Net.WebRequest]::Create($URL)
	$WebRequest.TimeOut = $TimeOut
	
	Try
	{
		#Attempt this
		$WebResponse = $WebRequest.GetResponse()
	}
	Catch [Exception]
	{
		#Output Exception if any occurs
		Write-Host $($_.Exception)
		
		return ([string]$Error[0].FullyQualifiedErrorId + " - " + [string]$Error[0])
	}
	Finally
	{
		#Close connection if one has been opened
		if ($WebResponse -ne $Null)
		{
			$WebResponse.Close()
		}
	}
	
	if ($WebResponse.StatusCode -eq "OK")
	{
		Write-Host "Domain Reachable"
		return $True
	}
	else
	{
		Write-Host "Domain Unreachable"
		return $False
	}
}

#Load DNS Dig exe file
#Based on codeproject site http://www.codeproject.com/KB/IP/DNS_NET_Resolver.aspx
$DNSDigExe = "C:\TEMP\DnsDig.exe"
[System.Reflection.Assembly]::LoadFile($DNSDigExe)

#Google DNS Server :)
$Server = "8.8.8.8"

#Master Array
$MasterArray = @()

#Domains in the domain list must start with www. - otherwise you will need to edit the code accordingly to reflect that they don't.
[array]$Domains = gc "C:\temp\domains.txt"

$DomainCount = $Domains.Count

if ($DomainCount -gt 0)
{
	for ($DomainCounter = 0; $DomainCounter -lt $DomainCount; $DomainCounter++)
	{
		$Status = "Processing Domain {0} of {1}" -f ($DomainCounter + 1), $DomainCount
		Write-Progress "Processing Domains" $Status -PercentComplete (($DomainCounter + 1) / $DomainCount * 100)
		
		$CurrentDomainWWW = $Domains[$DomainCounter]
		$CurrentDomain = $CurrentDomainWWW.Replace("www.","")
		
		Write-Host -ForeGroundColor "Yellow" $CurrentDomain
		
		$TempArray = @()
		$TempArray = "" | Select DomainName, PrimaryNS, MXRecord, WWWRecord, WebsiteResponds
		
		$TempArray.DomainName = $CurrentDomain
		$TempArray.PrimaryNS = Get-DNS $CurrentDomain "NS" $Server
		$TempArray.MXRecord = Get-DNS $CurrentDomain "MX" $Server
		$TempArray.WWWRecord = Get-DNS $CurrentDomainWWW "AName" $Server
		
		#If domain has a WWW record then check if url responds to HTTP response
		if ($TempArray.WWWRecord -ne $Null)
		{
			$TempArray.WebsiteResponds = Get-HTTPResponse "http://$CurrentDomainWWW" 20000
		}
		
		$MasterArray += $TempArray
	}
}

$MasterArray | ft
 
Back
Top Bottom