If you find yourself making changes to various types of DNS records on a Windows server, you may be wasting a lot of time. Why? Because it’s possible to create, modify, or remove any kind of DNS record with PowerShell!

Adam Bertram

Adam is a Microsoft Cloud and Datacenter Management Most Valuable Profressional (MVP) who specializes in Windows PowerShell. You can reach Adam at adamtheautomator.com or on Twitter at @adbertram.

PowerShell allows you to not only manage your DNS records from the command line but also to take those commands and put them into a script to automate all kinds of time-consuming tasks.

In this article, I will show you how to make that initial connection to your DNS servers from PowerShell and then go over a few common examples of tasks that you might find yourself needing to accomplish in the future.

Before we get too far, you need to be aware of a few prerequisites. First, I’m assuming you have permissions to read, modify, and remove DNS records from your Windows servers.

Second, I’ll be demonstrating a few concepts from DNS servers that are in an Active Directory domain with AD-integrated zones. PowerShell is still capable of managing zones and records outside of Active Directory but may not offer quite the same result as I’ll be showing you here.

Finally, you’ll need to ensure you have a version of the Remote Server Administration Tools (RSAT) installed on your client specific to your operating system.

Now that we have that out of the way, let’s start out by first ensuring the DNSServer module is available to us. To do that, I’ll use the Get-Module cmdlet.

Verifying that the DNSServer module is available

Verifying that the DNSServer module is available

Great! It looks like it is. Next, whenever exploring new functionality, it’s always a good idea to start with a Get PowerShell cmdlet to simply read an object. This ensures you can make the connection to the server and have permission to at least read objects.

Because we’re managing DNS records in this article, I’ll first start off by using Get-DNSServerResourceRecord. This cmdlet allows us to pull DNS records from one or many different DNS zones on a Windows DNS server.

I’m testing this in an Active Directory domain called mylab.local so, naturally, a mylab.local DNS zone has already been created on my domain controller. I’ll use the cmdlet to query that DNS zone on the domain controller called DC.

Reading DNS records with PowerShell

Reading DNS records with PowerShell

No red text—good! It looks like I can successfully pull all of the DNS records from a particular zone. What if I need just a particular type of record rather than all records? It’s not usual for me to fiddle with RV and NS records. I spend most of my time managing the A records. No problem: simply use the RRType parameter and specify an A. You’ll see that it only returns A records.

Now that I can read various DNS records, perhaps I’d like to modify a static record. One of our server names has changed and I need to be sure its DNS record is updated to reflect that. Changing DNS records is a little convoluted but, with some tenacity, we can still make it happen.

First, we’ll need to get two identical objects representing a DNS record. In this case, I’m pulling a DNS record for my MySQL server.

After I have the two objects, I’ll then change the IPV4 address on the new object to represent the IP address it has changed to. Unfortunately, it’s not quite as easy as simply setting a string. The IPV4Address property requires a type of System.Net.IPAddress in order to successfully make the change.

After the IP address is changed on the $new object, I can then use Set-DNSServerResourceRecord to force PowerShell to update the record on the server itself.

Finally, if I’d like to remove the record, the process is much simpler. I can simply pipe the results of Get-DNSServerResourceRecord directly to Remove-DNSServerResourceRecord.

You can do so much more with DNS records with PowerShell. To get a full list of all of the various commands in the DNSServer module, use the Get-Command cmdlet.

Also, always remember to use Get-Help if you’re curious about what a particular cmdlet might do! Get-Help is a great way to explore new cmdlets and functionality in PowerShell.

Win the monthly 4sysops member prize for IT pros

Share
2+

Related Posts

11 Comments
  1. Mattia Pasinetti 1 year ago

    Hi,

    how can i sobstitute the string

    $new.RecordData.IPv4Address = [System.Net.IPAddress]::parse('192.168.0.254')

    With a variable instead of IP?

     

    Thanks

    0

  2. Author
    Adam Bertram 1 year ago

    Yep, you could assign the IP to a variable like this:

    $ipAddress = '192.168.0.254'

    $new.RecordData.IPv4Address = [System.Net.IPAddress]::parse($ipAddress)

    0

  3. esxi 1 year ago

    nice post.

    One this is confusing tho. you said,.

     

    "One of our server names has changed and.."

    but the script does the IP change. And you said for that is "..I’ll then change the IPV4 address on the new object to represent the IP address it has changed to.."

     

    ==

    how can we change the host name dns record ? Same way , by creating 2 object, old & new ?

    0

  4. Author
    Adam Bertram 1 year ago

    I mentioned "server name changing" as a fictional use case. If that were the case, a company might have a CSV file with the server names and IPs those servers now need. From that, PowerShell can read the CSV and update the records accordingly.

    0

  5. Panzerbjrn 1 year ago

    This doesn't work:

    $new = $old = Get-DnsServerResourceRecord -ComputerName dc -ZoneName mylab.local -Name MYSQL

     

    This just creates a link to the same object, so you are not able to update the old object.

    1+

    • Author
      Adam Bertram 1 year ago

      Thanks for the feedback. Have you solved this a different way?

      0

      • Chris 8 months ago

        I don't know if there is a better way to do this, but the way I got around the issue Panzerbjrn mentioned was to set the $new variable in one command and the $old variable in another

        Once both variables are set separately, the rest of the instructions work fine.

        It seems like doing $new = $old = (....)  sets both variables to each other, so when you change $new it also changes $old.  When you run the Set-DnsServerResourceRecord command, it doesn't find the $old variable because it now has the newly identified IP address.
        I found this by doing echoing both the $new and $old variables after changing one or the other.
        Great instructions, I was in need of this 🙂

        0

      • Eugene Rosenfeld 3 months ago

        You can't use "$new = $old" because that just copies the reference, not the underlying objects.

        Instead, use "$new = $old.Clone()". That creates a deep copy the old record.

        0

  6. Jdashn 7 months ago

    Likely the best way to do it would be this:

    $old = get-dns...

    $new = $old.psobject.Copy()

    Hope this helps!

     

    1+

  7. Tim 6 months ago

    what to do if Get-DnsServerResourceRecord returns a collection of records? i.e.

    I'm able to update each record of the collection with:

    But getting the following error when trying to Set:

     

    0

  8. Mathew 3 months ago

    Adam, There is a question I would like to ask.

    What if we want to test whether a certain Reverse Lookup Zone has been created or not? I want to create DNS A records but before, need to confirm whether there is the reverse zone. If not reverse lookup zones have to be created and then the DNS A records.

    Thank you!

    1+

Leave a reply

Your email address will not be published. Required fields are marked *

*

CONTACT US

Please ask IT administration questions in the forum. Any other messages are welcome.

Sending
© 4sysops 2006 - 2017

Log in with your credentials

or    

Forgot your details?

Create Account