PowerShell Script : How to Backup DNS Zones – Improved

Hello World,

Based on some comments and feedback received on the post about backing up DNS Zones, we have decided to publish a new version of the script.  The logic remains the same. The main difference with the previous one is that we are using better the powershell capabilities.

Special thanks to Jeffrey Hicks .

This version of the script integrates the comments, advices and recommendations he made on the previous version of the script.

The Improved Backup DNS Script

You can use this script as a starting point for your own purposes and integrate it in your own scripts or backup/restore strategy.

The Script is quite simple to understand.  In the first section, we define some variables, In the next section, we using wmiobject to get DNS information and we export this information into a csv file using export-csv powershell cmdlet. Finally, we using the dnscmd.exe command to export zones information into text file and store them in the location you have defined.

That’s it

#--------------------------------------------------------------------------------------------#
# Script_Name : DNS_Backup.ps1
# Description : backup all DNS Zones defined on a Windows 2008 DNS Server
# Requirements : Windows 2008/R2 + DNS Management console Installed
# Version : 0.4 - Intergrated comments from Jeffrey Hicks
# Date : October 2011
# Created by Griffon
#-------------------------------------------------------------------------------------------#

#-- DEFINE VARIABLE------#

# Get Name of the server with env variable $DNSSERVER=get-content env:computername #---Define folder where to store backup  -----# $BkfFolder=”c:\windows\system32\dns\backup” #---Define file name where to store Dns Settings $StrFile=Join-Path $BkfFolder "input.csv” #—-Check if folder exists. if exists, delete contents--# if (-not(test-path $BkfFolder)) { new-item $BkfFolder -Type Directory | Out-Null } else { Remove-Item $BkfFolder”\*” -recurse } #—- GET DNS SETTINGS USING WMI OBJECT ——–# $List = get-WmiObject -ComputerName $DNSSERVER -Namespace root\MicrosoftDNS -Class MicrosoftDNS_Zone #----Export information into input.csv file ---# $list | Select Name,ZoneType,AllowUpdate,@{Name="MasterServers";Expression={$_.MasterServers}},DsIntegrated | Export-csv $strFile -NoTypeInformation #--- Call Dnscmd.exe to export dns zones $list | foreach { $path="backup\"+$_.name $cmd=”dnscmd {0} /ZoneExport {1} {2}” -f $DNSSERVER,$_.Name,$path Invoke-Expression $cmd } # End of Script # -----------------

Final Words

Using the comments from some our readers, we were able to create a better powershell script. If you are a little bit patient, I might publish the restore DNS script quite soon (meaning this week)

 

Till then

See ya

44 thoughts on “PowerShell Script : How to Backup DNS Zones – Improved

  1. Hi

    Ends with error:
    Missing expression after unary operator ‘-‘.
    At C:\dns_backup.ps1:33 char:2
    + – <<<< Namespace root\MicrosoftDNS -Class MicrosoftDNS_Zone
    + CategoryInfo : ParserError: (-:String) [], ParseException
    + FullyQualifiedErrorId : MissingExpressionAfterOperator

    thanks

  2. Hello there,

    Error problably comes from the fact that I had to break lines within the script…
    I might make a link to a downloadable version
    Anyway, It seems you’ve got it fixed..

    See ya around for more scripts :-))

  3. Hi ,

    Please help me in understanding below lines in script
    $list | foreach {
    $path=”backup\”+$_.name
    $cmd=”dnscmd {0} /ZoneExport {1} {2}” -f $DNSSERVER,$_.Name,$path
    Invoke-Expression $cmd
    }

  4. Hello Sunny,

    we simply loop through the items contains in the variable $list. While looping we simply execute the dnscmd.exe command.

    What’s in bracket are variables that are replaced with values found after -f operator.

    I hope this help

    Till next time

  5. Hi,

    Thanks for publishing this script. I am a bit new to Powershell, but am learning. I have a Microsoft Windows 2008 R2 server that runs DNS, and Powershell 3.0. I want to be able to back up my DNS Zones using your script. I seem to be getting tripped up with this command:

    $List = get-WmiObject -ComputerName $DNSSERVER -Namespace root\MicrosoftDNS -Class MicrosoftDNS_Zone

    get-WmiObject : Generic failure
    At D:\Scripts\DNS_Backup.ps1:32 char:10
    + $List = get-WmiObject -ComputerName $DNSSERVER -Namespace root\MicrosoftDNS
    -Cl …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ~~~
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], Managemen
    tException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.C
    ommands.GetWmiObjectCommand

    I think it is getting tripped up by the -class parameter. Is there a specific DNS Powershell module I need to first import onto that DNS server before running this script?

  6. Hello Kevin,

    We have seen this error when UAC is enabled and you run the powershell console as a standard user. Please try to run the script within a powershell console started with elevated privileges and check if this is working.

    To run powershell with elevated privilege, right-click the powershell console and select run as administrator

    Let us know if this is working

    Hope this help
    Till next time
    See ya

  7. Hi,

    Thank you for replying back. That did it! I am now running it as a Scheduled Task! Thanks again!

  8. hi

    when i run your script only the csv gets created in the correct backup location. the zone files get created in system32\DNS folder… i did not specify this path for backup. should be c:\backup\DNS

    thanks

  9. Hello Jermaine,

    I will need to have a look at it….. normally everything should go under backup…but I’ll check

    Till next time
    See ya

  10. Great script,

    One questions though and it is very similar to Sunny’s

    The outcome from:

    $list | foreach {
    $path=”backup\”+$_.name
    $cmd=”dnscmd {0} /ZoneExport {1} {2}” -f $DNSSERVER,$_.Name,$path
    Invoke-Expression $cmd
    }

    Doesn’t get saved anywhere does it? If it doesn’t what is the point of it?

  11. Hello Neuro,

    The syntax might seem special or complex but as you said in your last message, I’m assuming that you got it
    the line $cmd=”dnscmd {0} /ZoneExport {1} {2}” -f $DNSSERVER,$_.Name,$path basically can be split in two part
    the part one use {x} to define parameters to be passed
    the second part after the -f specify which variable needs to be passed
    so you could rewrite the command like dnscmd /zoneExport

    I hope this clear up your mind

    Till next time
    See ya

  12. Ahh yes I understand now thank you.

    One other question, since I don’t have a DNS server to test at the moment, what is the difference between the .csv (from get-WmiObject) and the .txt file (from dnscmd ). Are both needed and how would each be used?

  13. Hey Griffon,

    Sorry for bothering you, I understand the script now, but the problem is, now when I run just the

    “get-WmiObject -ComputerName $DNSSERVER -Namespace root\MicrosoftDNS -Class MicrosoftDNS_Zone”

    I get this error:

    “Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)”

    Any idea what might be causing this?

  14. Hello Neuro,

    are you trying to run the scrit from a remote computer ? You might need to check that the firewall or wmi services…..
    are you running the script in a powershell prompt, ensure that you run as an administrator…

    Till next time
    See ya

  15. Hello,

    When trying to run this script I get the bellow error:

    Get-Dns : Cannot bind parameter ‘RecordType’. Cannot convert value “Script.ps1” to type “DnsShell.RecordType”. Error: “Unable to match the identifier name Script.ps1 to a valid
    enumerator name. Specify one of the following enumerator names and try again: A, NS, MD, MF, CNAME, SOA, MB, MG, MR, NULL, WKS, PTR, HINFO, MINFO, MX, TXT, RP, AFSDB, X25, ISDN,
    RT, NSAP, NSAPPTR, SIG, KEY, PX, GPOS, AAAA, LOC, NXT, EID, NIMLOC, SRV, ATMA, NAPTR, KX, CERT, A6, DNAME, SINK, OPT, APL, DS, SSHFP, IPSECKEY, RRSIG, NSEC, DNSKEY, DHCID, NSEC3,
    NSEC3PARAM, HIP, NINFO, RKEY, SPF, UINFO, UID, GID, UNSPEC, TKEY, TSIG, IXFR, AXFR, MAILB, MAILA, ANY, TA, DLV, WINS, WINSR”
    At line:1 char:12
    + DNS backup Script.ps1
    + ~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Get-Dns], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,DnsShell.PowerShell.CmdLet.GetDns

    Also I was wondering you had any tips on how to do this as For Each loop (importing a list of my DC’s from a csv then outputting to the same CSV)

  16. Hello Chris,

    We have run the script on a 2012 R2 and no issues. If I read the error, I see there is a mention of a get-dns which looks like a powershell cmdlet… Later on I see something like DnsShell.Powershell.CmdLet.GetDns

    It looks like you are using a custom dns module (DnsShell module). The script we have provided does not use any custom module but simply call DNSCMD.EXE
    About your other question about any tips, If you have an Active Directory infrastructure, you should be using AD integrated zones. This ways you would only need to backup one DC only.

    If you still want to export dns from multiple servers, the easiest way would be to use Powershell remote Powershell using invoke-command

    Hope this help
    till next time
    see ya

  17. in case you’re curious this is what we ended up doing:

    ——
    $IPGDCs = ls -Path ‘AD:\OU=Domain Controllers,DC=domain,DC=domain,DC=com’ | select -ExpandProperty Name
    $mycol = @()
    Foreach ($IPGDC in $IPGDCs){
    $Props = [ordered]@{
    ‘Name’ = $IPGDC;
    ‘IPs’ = $null;
    ‘UseRootHints’ = $null;}

    $OBJ1 = New-Object -TypeName PSObject -Property $Props

    $DCDetails = Get-DNSServerForwarder -ComputerName $($OBJ1.Name)| select UseRootHint,@{name=’IPAddress’;expression={$_.IPAddress -join ‘,’}}
    $OBJ1.IPs = ($DCDetails.IPAddress)
    $OBJ1.UseRootHints = $DCDetails.UseRootHint
    $mycol += $OBJ1
    }#End of foreach

    $Mycol| select * | export-csv -Path c:\path.csv -NoTypeInformation

    ——

  18. Thanks for providing this script. I am attempting to put a process in place to backup our Windows 2012R2 Standalone non-integrated zones. I am running the script in Windows PowerShell ISE with run as Administrator while logged in with an account in the Local Administrators group. The script stalls at “Class:”. This being run from the server that I am trying to backup.

    Thank you for any assistances,
    -Michael

  19. Hello Michael,
    We have tried a gain on a 2012 R2 and it seems to work.
    Can you provide the full error message you are getting ?
    are you sure that there is not break in your line of code in the powershel ISE Admin (did you simply copy/paste the text from the blog into your ISE console)

    When we have that we might have a better view of what’s happening

    till next time
    see ya

  20. I would like to add some improvements to the Backup Script.
    This modifications allows to use a shared folder to drop the backup objetcs.
    The comments are in spanish but are almost the same as the original script.

    thank you so much for sharing this work.

    Hope this contribute help many others.

    Regards.

    #——————————————————————————————-#
    #– Definicion de variables——#

    #Obtener nombre del server con variable de entorno

    $DNSSERVER=get-content env:computername

    #—Definir carpeta donde guardar el backup—–#
    $BkfFolder=”\\contoso.com\bkp_dns”
    $BkpDefaltFolder=”c:\windows\system32\dns\backup”

    #—Definir archivo donde guardar las configuraciones de DNS
    $ArchivoConfig=Join-Path $BkfFolder “input.csv”

    #—-Verifica si existe la carpeta. Si existe borra el contenido–#
    if (-not(test-path $BkfFolder)) {
    new-item $BkfFolder -Type Directory | Out-Null
    } else {

    Remove-Item $BkfFolder”\*” -recurse
    }

    #—- Obtiene configuraciones de DNS atraves de WMI ——–#

    $lista = get-WmiObject -ComputerName $DNSSERVER -Namespace root\MicrosoftDNS -Class MicrosoftDNS_Zone

    #—-Exporta la informacion y la escribe en el archivo escrito en la variable $ArchivoConfig —#

    $lista | Select Name,ZoneType,AllowUpdate,@{Name=”MasterServers”;Expression={$_.MasterServers}},DsIntegrated | Export-csv $ArchivoConfig -NoTypeInformation

    #— Llamada a DNSCMD para exportar todas las zonas
    $lista | foreach {
    $path=”backup\”+$_.name
    $cmd=”dnscmd {0} /ZoneExport {1} {2}” -f $DNSSERVER,$_.Name,$path
    Invoke-Expression $cmd
    }

    #- Mueve todos los items de la carpeta por defecto al servidor de archivos

    copy-item $BkpDefaltFolder -destination $BkfFolder -recurse -verbose

    #-Remueve los archivos de la carpeta .\dns\backup del S.O.
    Remove-Item $BkpDefaltFolder”\*” -recurse

    #Fin del script
    #——————————————————————————————-#

  21. Hey David,

    Thank you for the improvements in the script
    and also thank for you sharing the information

    I hope indeed that this info will be useful to anyone out there….

    Thank you for the visit…
    Till next time
    See ya

  22. Hello Ian,

    If this is the only script you intend to publish into Microsoft Web site, we are OK with this. Thank you for notifying us and having left the original credits and link to our web site. Remember that our resources are free to use but copyrights might apply.

    Till next time
    See ya

  23. Using PS for this looks like an overkill. A simple batch script can do the job easily:
    FOR /F %%G IN (‘DNSCMD /ENUMZONES’) DO DNSCMD /ZONEEXPORT %%G export\%%G.dns
    It will backup all dns zones (AD integrated or standalone) into c:\windows\system32\dns\export

    If you want to filter zone type, you can add more parameter/argument into the ‘DNSCMD /ENUMZONES’

  24. Hello Anh,

    Thank you for your feedback and comments. You have indeed different way to perform this action. You can use the dnscmd or you can use powershell. It’s up to the user to choose which way he wants to use to perform the backup of the DNS

    Till next time
    See ya

  25. @Smithe621,

    do not hesitate the share the info provided here and participate in providing feedback, tips and tricks, and constructive comments
    Hope you and your buddies will enjoy the visit 🙂
    till next time
    See ya

  26. I am newbie here and in search of how to backup my dns, I got this useful script. However, I have some newbie questions.

    1. It is not clear for me what and what I should change to suit my environment. Please help newbie like me indicate what and what I need to change to suit environment.
    1. Once I run this ps script, will it be running automatically? Or I have to be running it every time I want to backup.
    2. What is the proper syntax for a remote server? (\\remotesever.com\folder) and env:network. Right?
    3. Does this script work for Win 2016 Server.
    Once again my apologies for any kind of inexperience here. I want to learn.
    Thanks
    -Schubborniel

  27. @Schulbert,

    1. you do not need to change anything. The script will detect automatically your settings and perform the actions
    2. The script will run only once when started. If needed to perform regular backups, use task scheduler to schedule a job that would call the script
    3. The script as is should be running locally on your dns server. If you want to execute the script from a remote machine, you will have to adapt the script
    4. The script should be working on Windows 2016 Server

    Hope this help
    Till next time
    See ya

  28. Great script
    Once we have it backup, please provide guidance on how to restore it

  29. @GB,
    Thanks for the visit and the positive feedback. If you search through the blog, you will find the restore script as well

    Till next time
    See ya

  30. @Jeff,

    Thanks for your visit and your feedback.. please note that there is also a script available to restore the DNS Zones

    Till next time
    See ya

  31. @Albi,

    Thank you for visiting our blog and sharing your experience
    As far as I remember, you cannot change the backup location… By default dnscmd.exe will copy the files under system32\dns\backup…. What you can do is adding some code to copy from original backup location to a different location (a network share) that would fits your requirements

    Hope this help
    Till next time
    See ya

  32. Hi,
    Can we run this on Windows 2016 and Windows 2019? I am getting stuck up at “$lista = get-WmiObject -ComputerName $DNSSERVER -Namespace root\MicrosoftDNS -Class MicrosoftDNS_Zone”it is asking for Class. any idea on this? What I need to provide as input?

  33. @Girish,

    Thank you for visiting our blog and providing feedback. Even if the script is a little bit out dated, this should be still working against Windows 2016 and later version (tested up to Windows 2022).
    If you have simply copy/paste the script and ran it, you will end up with the error about the Class….. Please ensure that you have no wrapped line in the script you are running. We have updated the post as well and changed the formatting of the script, you can also now copy/paste the script and see if this would work for you

    Till next time
    See ya

  34. Hi, I’m looking for a script that can export DNS data from an AD integrated “secure” dynamic zone, including the security ownership details for each DNS object, and restore that information if the zone has to be restored – does your script do this or do you know of one I can pilfer from somewhere? I need to be able to restore a zone from scratch if it has been deleted from AD.

  35. @Paul;
    Thank you for visiting our blog and providing some feedback. The script here will only do the export of the data also AD integrated zone but will not export the Security information. You will need to come up with an additional function or a separate script to do that.

    Hope this help
    Till next time
    See ya

Leave a Reply