Errors in script to Enable DNS Zone Transfers

Hi all,

I am trying to writ a script that will look at a DNS server, identify all the Zones, see if Dynamic Update is set to “NonsecureandSecure”, and if any zone are not set to that set it.

This is what I have come up with:

Begin Script*

#Script to identify all zones on a DNS server and enable zone transfers

Start-Transcript .\ZoneTransferInfo.txt

Get-DNSServerZone |ft -Property ZoneName, ZoneType, DynamicUpdate

Get-DNSServerZone | where DynamicUpdate -eq 'None' |ft -Property ZoneName, ZoneType, DynamicUpdate

$NoDynamicUpdate = Get-DNSServerZone | where DynamicUpdate -eq 'None' | FT ZoneName

foreach ($item in $NoDynamicUpdate) 
	{Set-DNSServerPrimaryZone -Name "$item" -DynamicUpdate "NonsecureandSecure" -PassThru}

Get-DNSServerZone |ft -Property ZoneName, ZoneType, DynamicUpdate

Stop-Transcript

End Script

I am getting a few errors that I am having trouble working through. When I run the foreach line I get the following error:

Set-DNSServerPrimaryZone : The zone Microsoft.PowerShell.Commands.Internal.Format.FormatEndData was not found on
server LAB-DC02.
At line:2 char:2

  • {Set-DNSServerPrimaryZone -Name “$item” -DynamicUpdate “NonsecureandSecure”
    -Pas …
    + CategoryInfo          : ObjectNotFound: (Microsoft.Power...t.FormatEndDa
   ta:root/Microsoft/...rverPrimaryZone) [Set-DnsServerPrimaryZone], CimExcep
  tion
    + FullyQualifiedErrorId : WIN32 9601,Set-DnsServerPrimaryZone

Any help/suggestion is greatly appreciated.

You’ve got some Formatting data creeping in somewhere you don’t want it. Understand that, once you run a format command like FT, you’re making the data useless for anything but screen display. I suspect this is your problem root:

$NoDynamicUpdate = Get-DNSServerZone | where DynamicUpdate -eq ‘None’ | FT ZoneName

$noDynamicUpdate doesn’t contain what you think it does. It contains a formatted table, with headers and columns and stuff. It’s no longer data. You should stop it with the Format-Table stuff, really. This is probably also a problem:

Get-DNSServerZone | where DynamicUpdate -eq ‘None’ |ft -Property ZoneName, ZoneType, DynamicUpdate

See https://powershell.org/kb/format-to-the-right/ for a general explanation, but as a rule, make sure you understand why Format-Table and Select-Object are different.

Thank You Don, that does make sense but brings up a whole new set of problems for me.

When I remove the | FT ZoneName the array now contains to much data. All I want in the array that I call with the next line is the ZoneName as that is the information required by the ‘Get-DNSServerPrimaryZone’ command so I can set the dynamic update setting.

How can I go about only outputting the ZoneNames informaton into the Array? I have tried looking it up and am experimenting with different syntax/commands/things I find but can’t seem to limit the array to just that information.

Thanks again!

Last paragraph of Don’s response:

See https://powershell.org/kb/format-to-the-right/ for a general explanation, but as a rule, make sure you understand why Format-Table and Select-Object are different.

Specifically look into Select-Object

Ed, Select-Object is the correct way to grab only the properties you want, while leaving a usable object that has usable data. In almost every case where you’ve used Format-Table, Select-Object is actually correct.

Yes, I was looking at that and made the following change:

$NoDynamicUpdate = Get-DNSServerZone | select-object ZoneName, DynamicUpdate | where DynamicUpdate -eq 'None'

This give me a output like:

ZoneName DynamicUpdate


0.in-addr.arpa None
127.in-addr.arpa None

All I need/want is the info under ZoneName:

0.in-addr.arp
127.in-addr.arpa
and etc…

As that is all that is needed for the:

Set-DNSServerPrimaryZone -Name ZoneName

field.

I can’t figure out how to just get that information in a array for the:

foreach ($item in $NoDynamicUpdate) 
	{Set-DNSServerPrimaryZone -Name "$item" -DynamicUpdate "NonsecureandSecure" -PassThru}

command to use.

I really appreciate all the guidance and information. I am learning alot

So, be patient with me in case I’m not understanding where you’re stuck :).

I want to make sure you’re not confusing the data that PowerShell has in memory, versus what PowerShell displays on the screen. For example, $NoDynamicUpdate doesn’t actually contain the “ZoneName,” “DynamicUpdate” headers, or the dashes. Those headers are added by an implicit call to Format-Table when you attempt to display the data. As the data sits in the variable, however, those headers don’t exist. $NoDynamicUpdate[0] would give me the first object (“row”), and $NoDynamicUpdate[0].ZoneName is the ZoneName property (“column”) from that first object.

So in your ForEach loop, $item is one ROW from $NoDynamicUpdate. $item.ZoneName would be the ZoneName property from that object.

-Name “$($item.ZoneName)”

Might be what you’re after. And just to make sure we’re correct on terminology:

$NoDynamicUpdate is a “collection,” not an array. $item will consist of one “object” at a time, and ZoneName is a “property” of that object.

Now, let’s go a different direction. You could also have done this:

$NoDynamicUpdate = Get-DNSServerZone | 
where DynamicUpdate -eq 'None' |
select -expand ZoneName

foreach ($zonename in $nodynamicupdate) {
Set-DNSServerPrimaryZone -Name "$zonename" -DynamicUpdate "NonsecureandSecure" -PassThru
}

Notice first that I used Where-Object prior to Select-Object. Always filter as far to the beginning of the command line as possible, for efficiency. Then, I used Select-Object to extract the only information I needed. The result is just a bunch of zone names - it isn’t a complex object with multiple properties anymore. I “pulled” the zone names out of the ZoneName properties. The result is that $NoDynamicUpdate is an array of strings, rather than being a collection of objects.

Even when you use Select to just pick one property, you still get output that is objects. Those objects just only have one property. Understanding the difference between objects, which are a data structure that contains values, and simple values like strings, is a key part of conquering PowerShell.

Really, as a total plug, get “Learn Windows PowerShell in a Month of Lunches.” It absolutely walks you through all of this. What you’re running into is what every PowerShell newcomer runs into, and the book’s designed to mitigate head-slamming-into-wall moments :).

Thank You very much, that got me going! I am going to grab that book you recommended and appreciate your patience with me.