Script to backup DNS zones

4 views
Skip to first unread message

Mike Leone

unread,
Oct 31, 2025, 10:50:16 AMOct 31
to NTPowershell Mailing List
So I want to write a script to periodically back up my DNS zones. But it appears it only works if I run it on the DNS server (in my case, a DC). Probably due to the Export-DnsServerZone command? That seems to default to saving *only* in c:\windows\system32\dns, from what I am experiencing.

# Requires DNSServer PS Module
Import-Module DnsServer

$CurrentVerbose = $VerbosePreference
$VerbosePreference = "continue"

$DnsServer = Get-ADDomainController | Select-Object -ExpandProperty HostName | Sort

$AllZones = Get-DnsServerZone -ComputerName $DNSServer | Where { $_.IsReverseLookUpZone -eq $False -and $_.ZoneType -eq "Primary" } | Select -ExpandProperty ZoneName

ForEach ($Zone in $AllZones)
{
$FileName = $Zone + ".dns.bak"
Write-Verbose "Zone = [$Zone]. Exporting to: $FileName"
Export-DnsServerZone -Name $Zone -ComputerName $DnsServer -FileName $FileName
}

$VerbosePreference = $CurrentVerbose

So, I'm looking for 2 things.

I would prefer to run this script remotely. I have a "script host" where I run all my scripts from (save GPOs, DHCP, etc). But I've tried to specify the location of the filename to export to, and all it seems to accept is a filename, not a filepath location (i.e., I can't use "C;\Temp\zoneinfo.txt".)

Am I just doing something wrong?

If not, how should I execute this? Invoke-Command of the script name directly on a DC? I've seen webpages that seem to use CIMSession, but I've never used that before. Not sure how I would securely save, then re-use, my credentials to establish the CIM session.

Do you have a better solution? What do YOU do (if anything), to save a backup of your DNS?

(a last step would be to move those files to a network share, so I make sure I know where they are in case I ever need them).

Thanks for any advice!


--

Mike. Leone, <mailto:tur...@mike-leone.com>

PGP Fingerprint: 0AA8 DC47 CB63 AE3F C739 6BF9 9AB4 1EF6 5AA5 BCDF
Photo Gallery: <http://www.flickr.com/photos/mikeleonephotos>

Michael B. Smith

unread,
Oct 31, 2025, 11:02:22 AMOct 31
to ntpowe...@googlegroups.com

The help for Export-DnsServerZone says:

 

    -FileName <String>

        Specifies a name for the export file. You can include a file path.

 

Did you try it?

 

Otherwise, just install rsat-adds and rsat-dns-server on your “script host” to get all the required commands.

--
You received this message because you are subscribed to the Google Groups "ntpowershell" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ntpowershell...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/ntpowershell/CAHBr%2B%2BjSP2ky9nYCjBmYor6CTdGn9AYFsiC6c_CPF79maV5APA%40mail.gmail.com.

Mike Leone

unread,
Oct 31, 2025, 11:09:44 AMOct 31
to ntpowe...@googlegroups.com
On Fri, Oct 31, 2025 at 11:02 AM Michael B. Smith <mic...@smithcons.com> wrote:

The help for Export-DnsServerZone says:

 

    -FileName <String>

        Specifies a name for the export file. You can include a file path.

 

Did you try it?


Many, many times. 

PS O:\software\PHA Scripts\dns> .\Backup-All-DNS-Zones.ps1
VERBOSE: Zone = [_msdcs.ads.pha.phila.gov]. Exporting to: C:\Temp\_msdcs.ads.pha.phila.gov.dns.bak
Export-DnsServerZone : Failed to export the zone content for _msdcs.ads.pha.phila.gov on server DC1WRK014.wrk.ads.pha.phila.gov to the file
C:\Temp\_msdcs.ads.pha.phila.gov.dns.bak.
At O:\software\PHA Scripts\dns\Backup-All-DNS-Zones.ps1:13 char:2
+     Export-DnsServerZone -Name $Zone  -ComputerName $DnsServer  -File ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (_msdcs.ads.pha.phila.gov:root/Microsoft/...S_DnsServerZone) [Export-DnsServerZone], CimException
    + FullyQualifiedErrorId : WIN32 13,Export-DnsServerZone

 

Otherwise, just install rsat-adds and rsat-dns-server on your “script host” to get all the required commands.


I have all those RSATs and the PS modules. This command just doesn't work remotely at all. Even directly on the DC, it only works with a filename, not a filepath.

An important point to note, the zone file name doesn’t seem to accept a full file path. You simply can enter the file name you want to use without a path. The file that you create during the export is created in the DNS folder located at C:WindowsSystem32dns.

 

Michael B. Smith

unread,
Oct 31, 2025, 11:24:09 AMOct 31
to ntpowe...@googlegroups.com

Those fun facts would’ve been good to include in your original email.

 

You’re right. It’s broken. I’ve verified in my test environment.

 

First, I’d file a bug report.

 

Second, I’d use invoke-command with the secrets management module.

 

There are several problems with that cmdlet. The one you found of course, and it doesn’t have any controls for overwriting the existing file (or not).

 

You might consider using dnscmd.exe /zoneexport instead.

Mike Leone

unread,
Oct 31, 2025, 11:30:45 AMOct 31
to ntpowe...@googlegroups.com
On Fri, Oct 31, 2025 at 11:24 AM Michael B. Smith <mic...@smithcons.com> wrote:

Those fun facts would’ve been good to include in your original email.


Well, I didn't find that webpage until after I sent the email. And my original email did say:

"But I've tried to specify the location of the filename to export to, and all it seems to accept is a filename, not a filepath location (i.e., I can't use "C;\Temp\zoneinfo.txt".)"

You’re right. It’s broken. I’ve verified in my test environment.

 

First, I’d file a bug report.


Dunno how to do that, as I've never done it. :-)
 

Second, I’d use invoke-command with the secrets management module.

 

There are several problems with that cmdlet. The one you found of course, and it doesn’t have any controls for overwriting the existing file (or not).

 

You might consider using dnscmd.exe /zoneexport instead.


But that webpage I linked to says:

The DNSCMD command like the PowerShell command doesn’t like a file path entered for the resulting exported DNS file.

I haven't had time to try that myself, but I don't suppose it's wrong.

I just don't want to run the script locally, only because we're in the process of replacing DCs, and I don't want my co-worker to forget to set up the script on the new DC. If I could run it remotely, then that particular sub-issue goes away ...
 

Michael B. Smith

unread,
Oct 31, 2025, 12:02:31 PMOct 31
to ntpowe...@googlegroups.com

If you run it remotely using invoke-command, can copy the output file locally.

Mike Leone

unread,
Oct 31, 2025, 12:32:22 PMOct 31
to ntpowe...@googlegroups.com
Yeah, I think I'm gonna go with this. It exports the zones, then moves the files.
Just need to add a section to email me so I know it worked. And test it via Invoke-Command ....
The export of the server settings is there, mostly because I can. LOL

I wonder if I should expand it to include reverse zones. What do you think?

------------------------------------
# Requires DNSServer PS Module
Import-Module DnsServer

$RunDate = Get-Date -Format yyyy-MM-dd
$DestFilePath = "\\DC1FIL020\netadmin\DNS-Backups\" + $RunDate
if (-not (Test-Path -Path $DestFilePath)) {
  $null = New-Item -Path $DestFilePath -ItemType directory

}

$CurrentVerbose = $VerbosePreference
$VerbosePreference = "continue"

$DnsServer = Get-ADDomainController | Select-Object -ExpandProperty HostName | Sort
$AllZones = Get-DnsServerZone -ComputerName $DNSServer | Where { $_.IsReverseLookUpZone -eq $False -and $_.ZoneType -eq "Primary" } | Select -ExpandProperty ZoneName
ForEach ($Zone in $AllZones)
{
$FileName = $Zone + ".dns.bak"
Write-Verbose "Zone = [$Zone]. Exporting to: $FileName"
Export-DnsServerZone -Name $Zone -ComputerName $DnsServer -FileName $FileName
$SourceFilePath = "C:\Windows\system32\dns\" + $FileName
$FileExists = (Test-Path $SourceFilePath)
IF ($FileExists)
{
$DestFileName = $DestFilePath + "\" + $FileName
Move-Item -Path $SourceFilePath -Destination $DestFileName
}
ELSE
{
Write-Verbose "That there file don't exist!! $SourceFilePath : $FileExists"
}
}

# Export DNS server-wide settings (as much as possible via PowerShell)
$ServerSettingsXMLFilePath = $DestFilePath + "\" + $DnsServer + ".settings.XML"
$ServerSettingsTXTFilePath = $DestFilePath + "\" + $DnsServer + ".settings.TXT"

Get-DnsServerSetting -ComputerName $DnsServer | Export-Clixml -Path $ServerSettingsXMLFilePath
Get-DnsServerSetting -ComputerName $DnsServer | Out-File -FilePath $ServerSettingsTXTFilePath

$VerbosePreference = $CurrentVerbose
------------------------------------

 Directory of P:\DNS-Backups\2025-10-31

10/31/2025  12:30 PM    <DIR>          .
10/31/2025  12:30 PM    <DIR>          ..
10/31/2025  12:30 PM               582 DC1WRK013.wrk.ads.pha.phila.gov.settings.TXT
10/31/2025  12:30 PM            10,414 DC1WRK013.wrk.ads.pha.phila.gov.settings.XML
10/31/2025  12:30 PM               988 TrustAnchors.dns.bak
10/31/2025  12:30 PM           234,268 wrk.ads.pha.phila.gov.dns.bak
10/31/2025  12:30 PM             5,108 _msdcs.ads.pha.phila.gov.dns.bak



Michael B. Smith

unread,
Oct 31, 2025, 1:09:23 PMOct 31
to ntpowe...@googlegroups.com

I think reverse zones are important. That’s kind of a personal choice. 😊

Mike Leone

unread,
Oct 31, 2025, 2:29:01 PMOct 31
to ntpowe...@googlegroups.com
On Fri, Oct 31, 2025 at 1:09 PM Michael B. Smith <mic...@smithcons.com> wrote:

I think reverse zones are important. That’s kind of a personal choice. 😊


true, true.

I also added this, to get all the full blown output from DNSCMD. Dunno if I'll ever need it, but what the hey ...:

$LocalDNSdirectory = "C:\Windows\System32\dns\"
DnsCMDSourceFilePath = $LocalDNSdirectory + "DnsSettings.txt"
$DnsCMDDestFilePath = $DestFilePath + "\" + $DnsServer + ".DNSCMD.Settings.TXT"


Get-DnsServerSetting -ComputerName $DnsServer | Export-Clixml -Path $ServerSettingsXMLFilePath
Get-DnsServerSetting -ComputerName $DnsServer | Out-File -FilePath $ServerSettingsTXTFilePath

# Export full blown DNS server settings via DNSCMD

DNSCMD $DnsServer /ExportSettings

Move-Item -Path $DnsCMDSourceFilePath -Destination $DnsCMDDestFilePath

 

Mike Leone

unread,
Oct 31, 2025, 2:58:53 PMOct 31
to ntpowe...@googlegroups.com
On Fri, Oct 31, 2025 at 1:09 PM Michael B. Smith <mic...@smithcons.com> wrote:

I think reverse zones are important. That’s kind of a personal choice. 😊


This is odd. Why did these zones not export? I got every other zone and reverse. Do those zones have some special property I should be filter out for?

VERBOSE: ERROR!! Exporting 0.in-addr.arpa.
VERBOSE: That there file don't exist!! File: C:\Windows\System32\dns\0.in-addr.arpa.dns.bak : False
VERBOSE: ERROR!! Exporting 127.in-addr.arpa.
VERBOSE: That there file don't exist!! File: C:\Windows\System32\dns\127.in-addr.arpa.dns.bak : False
VERBOSE: ERROR!! Exporting 255.in-addr.arpa.
VERBOSE: That there file don't exist!! File: C:\Windows\System32\dns\255.in-addr.arpa.dns.bak : False
DC1WRK013.wrk.ads.pha.phila.gov completed successfully.
Command completed successfully.

 TRY {
Export-DnsServerZone -Name $Zone -ComputerName $DnsServer -FileName $FileName -ErrorAction SilentlyContinue
} CATCH {
Write-Verbose "ERROR!! Exporting $Zone."
}
$SourceFilePath = $LocalDNSdirectory + $FileName

$FileExists = (Test-Path $SourceFilePath)
IF ($FileExists)
{
$DestFileName = $DestFilePath + "\" + $FileName
Move-Item -Path $SourceFilePath -Destination $DestFileName
}
ELSE
{
Write-Verbose "That there file don't exist!! File: $SourceFilePath : $FileExists"
}

Mike Leone

unread,
Oct 31, 2025, 3:33:59 PMOct 31
to ntpowe...@googlegroups.com
On Fri, Oct 31, 2025 at 12:02 PM Michael B. Smith <mic...@smithcons.com> wrote:

If you run it remotely using invoke-command, can copy the output file locally.


Oddly, if I run it as user me, remotely using invoke-command, I don't get the actual AD zone files. 
Yet if I run the exact same script as the same user (me)  locally on the DC, I *do* get the  AD zone files .... invoke-command and all

So something's not quite right .... This would be the last step I need. Of course, it's the most important step, to save those AD zones ...

Am I missing something about invoke-command?

$StartTime = Get-Date


$DnsServer = Get-ADDomainController | Select-Object -ExpandProperty HostName | Sort

Write-Verbose "Invoking script on $DnsServer Start Time: $StartTime"
Write-Verbose `n

$VerbosePreference = $CurrentVerbose

Invoke-Command -ComputerName $DnsServer -ScriptBlock {

$VerbosePreference = "SilentlyContinue"


# Requires DNSServer PS Module
Import-Module DnsServer

and so on, as shown before ...




Michael B. Smith

unread,
Oct 31, 2025, 3:47:54 PMOct 31
to ntpowe...@googlegroups.com

Change

 

Write-Verbose "ERROR!! Exporting $Zone."

To

 

Write-Verbose "ERROR!! Exporting $Zone, error $( $error[ 0 ] )."

In order to get the actual error.

 

From: ntpowe...@googlegroups.com <ntpowe...@googlegroups.com> On Behalf Of Mike Leone
Sent: Friday, October 31, 2025 2:59 PM
To: ntpowe...@googlegroups.com
Subject: Re: [ntpowershell] Script to backup DNS zones

 

On Fri, Oct 31, 2025 at 1:09PM Michael B. Smith <mic...@smithcons.com> wrote:

--

You received this message because you are subscribed to the Google Groups "ntpowershell" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ntpowershell...@googlegroups.com.

Michael B. Smith

unread,
Oct 31, 2025, 3:48:19 PMOct 31
to ntpowe...@googlegroups.com

Try specifying the credentials for invoke-command, and -RunAs if available.

Mike Leone

unread,
Oct 31, 2025, 3:53:04 PMOct 31
to ntpowe...@googlegroups.com
On Fri, Oct 31, 2025 at 3:48 PM Michael B. Smith <mic...@smithcons.com> wrote:

Try specifying the credentials for invoke-command, and -RunAs if available.


I tried the credential, with a Get-Credential and passing that on the Invoke-Command line. Didn't help.

Is -RunAs an option for Invoke-Command? You mean like this:

Invoke-Command -ComputerName $Server -Credential $Cred -ScriptBlock { Start-Process powershell.exe -Verb RunAs -ArgumentList ('<Your Elevated Command or Script>')




Michael B. Smith

unread,
Oct 31, 2025, 3:55:48 PMOct 31
to ntpowe...@googlegroups.com

You made me go look. It’s called RunAsAdministrator.

Mike Leone

unread,
Oct 31, 2025, 4:14:08 PMOct 31
to ntpowe...@googlegroups.com
OK, I'll try that next week. For now, I'll run it as me, just so I can get a copy before the weekend.

next week I'll try and figure out the invoke-command. Otherwise I will have to run it locally on the DC, which means I must assign the AD account I use to run scripts the "log on as a batch" access right. Oh, and sign the script, so it'll run there.

Thanks for all your help!

Wright, John M

unread,
Nov 3, 2025, 9:31:00 AMNov 3
to ntpowe...@googlegroups.com

Export, then move (or rather robocopy) is all I do in my script.

 

FWIW, I also include all the zones.  The exports are just text files so you can remove portions of it after the fact if you decide you don’t want them restored.

 

--

John Wright

IT Support Specialist

1800 Old Bluegrass Avenue, Louisville, KY 40215

502.708.9953

Please submit IT requests to Hazelwoo...@bluegrass.org

24 Hour Helpline 1.800.928.8000

  

CONFIDENTIALITY NOTICE: This message contains confidential information and is intended only for the individual(s) addressed in the message. If you are not the named addressee, you should not disseminate, distribute, or copy this e-mail. If you are not the intended recipient, you are notified that disclosing, distributing, or copying this e-mail is strictly prohibited.

 

From: ntpowe...@googlegroups.com <ntpowe...@googlegroups.com> On Behalf Of Mike Leone
Sent: Friday, October 31, 2025 12:32 PM
To: ntpowe...@googlegroups.com
Subject: Re: [ntpowershell] Script to backup DNS zones

 

EXTERNAL EMAIL - This email was sent by a person from outside your organization. Exercise caution when clicking links, opening attachments or taking further action, before validating its authenticity.

Secured by Check Point

Mike Leone

unread,
Nov 3, 2025, 9:38:49 AMNov 3
to ntpowe...@googlegroups.com
On Mon, Nov 3, 2025 at 9:31 AM Wright, John M <John....@newvista.org> wrote:

Export, then move (or rather robocopy) is all I do in my script.


That's what I'm doing. Export zones with the Powershell command, then (for good measure) expor with DNSCMD, and I then move (using the Powershell move-item) all those files to a network share, in a sub-folder with the run date.
 

FWIW, I also include all the zones.  The exports are just text files so you can remove portions of it after the fact if you decide you don’t want them restored.



My problem is, it isn't running correctly if I execute it remotely. It does execute correctly if I execute it locally on the DC (using the same AD account). So in order to run it as a scheduled task on the DC, I need to grant the account "log on as a batch" access right, and I don't seem to see that on the local gpedit. I can change the domain DC policy and add the account, I guess.

Is that how you do it? Or do you not have these issues as a scheduled task?

Wright, John M

unread,
Nov 3, 2025, 9:42:11 AMNov 3
to ntpowe...@googlegroups.com

No, my runs as a scheduled task without a problem.  But I’ll look over this thread more later and see if I can figure out what’s going on.

 

--

John Wright

IT Support Specialist

1800 Old Bluegrass Avenue, Louisville, KY 40215

502.708.9953

Please submit IT requests to Hazelwoo...@bluegrass.org

24 Hour Helpline 1.800.928.8000

  

CONFIDENTIALITY NOTICE: This message contains confidential information and is intended only for the individual(s) addressed in the message. If you are not the named addressee, you should not disseminate, distribute, or copy this e-mail. If you are not the intended recipient, you are notified that disclosing, distributing, or copying this e-mail is strictly prohibited.

 

From: ntpowe...@googlegroups.com <ntpowe...@googlegroups.com> On Behalf Of Mike Leone
Sent: Monday, November 3, 2025 9:39 AM
To: ntpowe...@googlegroups.com
Subject: Re: [ntpowershell] Script to backup DNS zones

 

EXTERNAL EMAIL - This email was sent by a person from outside your organization. Exercise caution when clicking links, opening attachments or taking further action, before validating its authenticity.

Secured by Check Point

 

On Mon, Nov 3, 2025 at 9:31AM Wright, John M <John....@newvista.org> wrote:

Export, then move (or rather robocopy) is all I do in my script.

 

That's what I'm doing. Export zones with the Powershell command, then (for good measure) expor with DNSCMD, and I then move (using the Powershell move-item) all those files to a network share, in a sub-folder with the run date.

 

FWIW, I also include all the zones.  The exports are just text files so you can remove portions of it after the fact if you decide you don’t want them restored.

 

 

My problem is, it isn't running correctly if I execute it remotely. It does execute correctly if I execute it locally on the DC (using the same AD account). So in order to run it as a scheduled task on the DC, I need to grant the account "log on as a batch" access right, and I don't seem to see that on the local gpedit. I can change the domain DC policy and add the account, I guess.

 

Is that how you do it? Or do you not have these issues as a scheduled task?

 

--

You received this message because you are subscribed to the Google Groups "ntpowershell" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ntpowershell...@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages