• Notice regarding image hosts and attachments. See here.

PowerShell script to check DNS for domains

Soldato
Joined
25 Mar 2004
Posts
16,056
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