If you perform DNS administration on Windows Server systems, you might remember the columns I wrote years ago—such as "Scripting DNS Setup"—about Dnscmd, a powerful command-line tool that lets you do just about any kind of DNS administration. Now, I don't want to beat up on Dnscmd, but I was pretty happy to see that my command-line DNS administration work now has a new assistant, and that assistant comes in the form of 100 PowerShell cmdlets. This month, I want to show you 3 of those 100 cmdlets, as well as a couple examples of how you can take a simple PowerShell “power tool” and make it even more powerful.

Set 'Em Up

First things first. What version of Windows Server will you need in order to use these 100 new cmdlets? I haven’t yet tried all 100 of them, but as far as I can see, all you need to run these DNS-oriented cmdlets against a Windows Server 2008 R2 system is a Windows 8 workstation that you've joined to a domain and upon which you've downloaded and installed the Remote Server Administration Tools (RSAT) for Windows 8. At that point, type:

get-command *-dnsserver*

and you’ll see the 100 DNS cmdlets. Of course, if you already have a Windows Server 2012 system, just install the built-in DNS management tools and you’ll get the DNS cmdlets. OK, let’s put them to work.

Two Gets

By now, you’ve probably seen that a good strategy for testing a block of PowerShell cmdlets is to give the Get- cmdlets a try. Get-dnsserveredns tells you whether your DNS server has Extensions to DNS enabled (and it should, as in every case I’ve come across). Get-dnsserverrecursion tells you whether your DNS server will accept queries for zones that don’t exist on that server. Suppose I ask my local AD-centric DNS server to find www.microsoft.com; I don’t run Microsoft’s public zone, so unless I have recursion enabled on my local DNS server, the server won’t go running around the Internet to resolve my query.

Why would this functionality be useful? Unfortunately, the number of jerks out there using DNS servers to create a nasty kind of distributed, “amplified” Denial of Service (DoS) attack has grown tremendously in the past few years, prompting many of us to have to disable recursion (it’s on by default) on our DNS servers and find resolvers elsewhere. In such a case, it’s nice to be able to check on a given DNS server or, of course, to use PowerShell’s great remoting tools. Thus, if you had, say, five DNS servers named D1, D2, D3, D4, and D5, you could get one simple report of their recursion status with this command:

invoke-command -computername d1,d2,d3,d4,d5 -scriptblock {get-dnsserverrecursion|select pscomputername,enable}

I've shown you the invoke-command cmdlet before, and as I said then, the -scriptblock parameter tells the remote computers what command to execute between the braces. In those braces, you see the DNS cmdlet and then a Select statement that shows you the name of the computer that you ran this cmdlet on, as well as the result.

One Add

I found another Server 2012 DNS cmdlet, add-dnssecondaryzone, to be quite a time-saver recently. I was setting up a new DNS server that I wanted to be a secondary server for a bunch of the DNS zones that I host. Don’t misunderstand: Making a Windows DNS server into a secondary server for an existing domain isn’t difficult to do with the GUI or Dnscmd, but it’s tedious. It took just a moment to figure out that I could make the DNS server that I was sitting at a secondary DNS server for a domain named bigfirm.com with a primary IP address of 71.23.1.5, and that I wanted its zone data stored on a text file named bigfirm.com.dns:

add-dnssecondaryzone bigfirm.com "bigfirm.com.dns" 71.23.1.5

I immediately thought, OK, I have to do that with seven domains, and all I have to do is change that zone name in two places. So, let’s see, first I’ll store the domain names in an array, which is nothing but a list of the domain names in quotes with commas between them:

$zones="bigfirm.com","minasi.com","mmco.com","pungogrill.com","thesoftwareconspiracy.com","softwareconspiracy.com","steadierstate.com",

and then I can use the pipeline and the foreach-object command to feed each zone name to add-dnssecondaryzone, using the built-in $_ variable that contains whatever is in the pipeline at the moment. That lets me type this:

$zones | foreach-object {Add-DnsServerSecondaryZone $_ $_+".dns" "71.23.1.5"}

I freely admit that I got a bit ahead of myself there, but believe me, it worked, and on the first try! So I think it’s about time to get off my duff and cover ForEach-Object and the $_ pipeline tools—next time.