July 19, 2018

PowerShell :: export DNS zones to a hosts file

PowerShell ISE logo
(Last Updated On: 17th September 2016)

Picture the scene!  Your data centre has caught fire so you grab you disaster recovery jump kit and run off to the standby site to start powering things up.  Whether you are using VMware SRM, Veeam replication or block level SAN replication you are going to need to connect to some servers / appliances right?  So you try to connect to VMware by the FQDN then realise that you aren’t getting anywhere because you’ve lost DNS!  Fortunately you have a dodgy excel spreadsheet full of servers and their IP addresses that was last updated about 6 months ago and you can start muddling through.

This script is designed to get rid of this problem.  You simply schedule it on a domain controller and then set the $outputFilePath to some other location, maybe a USB stick at the DR site via a samba share?  When you DR, just overwrite your local hosts file with the output file from this script and you have to up to date name resolution.

You never knew you needed it until you saw it right?

Maybe there was no fire, maybe you have just lost your domain controllers and now you need to do a restore but your backup server is trying to use FQDN’s in the restore process?  Replace the host file on the backup server with this and resolve away 😀

$outputFilePath = "C:\hosts"

function FindTheIP ($HostName){
Try
{
$IPAddress = Resolve-DnsName $HostName -ErrorAction Stop | ? Type -eq "A" -ErrorAction Stop | select IPAddress
}
Catch
{
$IPAddress = $A_Records | ? HostName -eq ($HostName.Split("."))[0] | select RecordData.IPv4Address.IPAddressToString
}
if ($IPAddress)
{
return ($IPAddress.IPAddress)
}
}

function WriteOut ($Line){
Write-Debug $Line
Write-Output $Line >> $outputFilePath
}

$ErrorActionPreference = "Continue"

Try
{
Write-Output ("##### Start of the generated Host File
###
###
### Generated on: " + (get-date) +"
###
###
### How Exciting!
###
###
#####") > $outputFilePath
Write-Debug "Successfully cleared $outputFilePath"
}
Catch
{
Write-Error "Cant write to $TargetFile"
exit(2)
}

Try
{
$PrimaryForwardZones = Get-DnsServerZone | Where-Object {
$_.IsReverseLookupZone -eq $false -and
$_.ZoneType -eq "Primary" -and
$_.Zonename -ne "TrustAnchors"
}
Write-Debug ("Got " + $PrimaryForwardZones.Length + " DNS Zones")
}
Catch
{
Write-Error "Can't get DNZ zones"
exit(2)
}

$PrimaryForwardZones | foreach {
$Suffix = $_.ZoneName
WriteOut ("########## Begin Zone $Suffix ##########")
Try
{
$ResourceRecords = $_ | Get-DnsServerResourceRecord -ErrorAction Stop
Write-Debug ("Successfully got "+$ResourceRecords.length+" records for $Suffix")
}
Catch
{
Write-Error "Couldn't get records for $Suffix"
}
$ResourceRecords | foreach {
if($_.RecordType -eq "A")
{
$IPAddress = $_.RecordData.IPv4Address.IPAddressToString
}
if($_.RecordType -eq "CNAME")
{
$IPAddress = FindTheIP($_.RecordData.HostNameAlias)
if (! $IPAddress)
{
Write-Error ("Couldn't resolve " + $_.RecordData.HostNameAlias + " which is the alias for "+ $_.HostName )
}
}
if ($IPAddress)
{
WriteOut($IPAddress+"`t"+$_.Hostname+"."+$Suffix)
}
Remove-Variable IPAddress -ErrorAction SilentlyContinue ## Clear up so we don't reuse old data in later calls
}
}

Previous «
Next »

Simon is a sysadmin for a global financial organisation and specialises in Windows, security and automation.

Leave a Reply

Subscribe to SYNACK via Email

%d bloggers like this: