DiscoPosse – Using the chicken to measure IT
Technology, Cycling, Music and Madness


Technology

May 15, 2012

Microsoft DNS record updates using PowerShell and DNSCMD

More articles by »
Written by: Eric
Tags: , , , , , ,

UPDATE TO THIS POST:

Hi folks! some of the comments about records that are listed with (same as parent folder) as the name caused me to make an update. I’ve noted the updates in the following post:

http://www.discoposse.com/index.php/2013/04/14/updating-same-as-parent-folder-records-with-dnscmd-and-powershell/

I have also updated the code below to reflect the new code.

ORIGINAL POST:

There are occasions where we need to do bulk DNS record management such as create and update a large series of records for IP network changes or BCP testing. The environment I am working with is a Microsoft DNS zone. It can be a standard Primary, or an Active Directory Integrated zone. Either type will work with the process we are creating here.

This is not a typical and common process as DNS is often self-managing and dynamic. Let’s assume that you have a number of records from devices that cannot dynamically update, and you are currently using static A and CNAME records to define them.

Because this is not a commonly occurring task, there are no native PowerShell CmdLets to do this. What we can do however is get the best of breed by using PowerShell to parse a file and craft the command line to use the Microsoft DNSCMD command line tool.

This process assumes that your records are all located in the root if the zone you define with the $DNSZone variable. The idea is that you can take this concept and flavour to taste for your particular needs.

The zone that we are managing for our example script is shown here:

To update the zone, we have to use a CSV file which is located in the same directory as the script, or you can define the full drive letter and path with the $InputFile variable if you so desire. The CSV file requires a header row which is name,type,address to give us our attributes for each object when we parse the file.

The script logic is fairly simple:

  1. Define our zone info (server and zone name)
  2. Import the CSV file into an array
  3. Loop through the array
  4. Create a delete command line and use the Invoke-Expression CmdLet to execute it
  5. Create an add command line and use the Invoke-Expression CmdLet to execute it

I haven’t added any fancy logging or anything, but there is some Write-Host CmdLets used to output the commands to screen so that you can ensure that they are coming out as expected.

Fair warning on this one. Because we are using the Invoke-Expression CmdLet to launch the DNSCMD executable, we don’t have the luxury of a -WhatIf option. You can comment out the Invoke-Expression lines and run using just the Write-Host output as a sanity check on your structure. And by “can” I mean you very definitely should!

The script can be downloaded at my TechNet Gallery here: http://gallery.technet.microsoft.com/Update-DNS-records-with-da10910d

Here is the script:

# Environment Setup
$DNSServer = “DC1″
$DNSZone = “corp.discoposse.com”
$InputFile = “dnsrecords.csv”

# Read the input file which is formatted as name,type,address with a header row
$records = Import-CSV $InputFile

# Now we loop through the file to delete and re-create records
# DNSCMD does not have a modify option so we must use /RecordDelete first followed by a /RecordAdd

ForEach ($record in $records) {

# Capture the record contents as variables
$recordName = $record.name
$recordType = $record.type
$recordAddress = $record.address

# Build our DNSCMD DELETE command syntax
$cmdDelete = “dnscmd $DNSServer /RecordDelete $DNSZone $recordName $recordType $recordAddress /f”

# Build our DNSCMD ADD command syntax
$cmdAdd = “dnscmd $DNSServer /RecordAdd $DNSZone $recordName $recordType $recordAddress”

# Now we execute the command
Write-Host “Running the following command: $cmdDelete”
Invoke-Expression $cmdDelete

Write-Host “Running the following command: $cmdAdd”
Invoke-Expression $cmdAdd
}

So let’s run the script and see the results. This is the output from the script:

And now the resulting zone configuration shows the new updated records as per our CSV file:

While this may be a very simple example, it is meant to be a starting point to show you how to make the best of a situation where there is not a native PowerShell CmdLet. Being able to use hybrid scripting tools and techniques is a great thing to have in your toolkit of skills.

I hope that you find this useful!

 



About the Author

Eric





 
 

 
featured_powershell

Updating (same as parent folder) records with DNSCMD and PowerShell

In an earlier post on the site (Microsoft DNS record updates using PowerShell and DNSCMD) I noted how PowerShell cannot natively update records in MS DNS, however we could leverage the DNSCMD command and pass parameters using a...
by Eric
1

 
 
sharepoint

DiscoPosse Review: Exploring Microsoft SharePoint 2013 – New Features and Functions

For anyone who has been involved with SharePoint 2007 or 2010, this book is an excellent companion to help you with the transition to the new SharePoint 2013 environment. The new Microsoft Press book Microsoft SharePoint 2013: ...
by Eric
0

 
 
scrumdevbook

DiscoPosse Review: Professional Scrum Development with Microsoft Visual Studio 2012

Hot on the heels of reading The Phoenix Project, I finally got a chance to finish up reading the Professional Scrum Development with Microsoft Visual Studio 2012 from Microsoft Press. One thing that I can say for sure is that t...
by Eric
0

 

 
powercli-logo

PowerCLI – Add Multiple VLAN Port Groups to vSphere Cluster Standard vSwitches

A recent change to my networking environment added the requirement to put different VM guests onto different VLANs according to their role. This is a fairly common configuration for a lot of virtualized datacenters. What is als...
by Eric
2

 
 
featured_powershell

CSV, yeah you know me! – PowerShell and the Import-Csv CmdLet – Part 3

This was a long overdue post, so thanks for sticking with me while I finally got back on track with our CSV, yeah you know me series (Here are Part 1 and Part 2). As I’d mentioned in the closing of Part 2, we want to be a...
by Eric
0

 

 
featured_powershell

Finding RDP sessions on servers using PowerShell

Have you ever needed to use RDP to get to a server console for some local admin work and then been bounced out because there are already active sessions? Or have you had your Active Directory account locked out because of an op...
by Eric
8

 



Join Zipcar and get $50 in free driving Join Zipcar and get $50 in free driving Join Zipcar and get $50 in free driving

11 Comments


  1. Lakend

    Hi,

    This is great script and very usefull to me. Is it possible to create PTR record as well?

    Thanks

    Lakend


  2. Hi Lakend,

    You sure can! All that you need to do is adjust the DNSCMD parameters for the TYPE field. Because we pass this into the command through PowerShell Parameters read from the file ($recordType) you just change the line in your text file to have the type column as PTR.

    That should do all you need to do. Let me know if that works :)

    Eric


  3. zizou

    Hi Eric!

    Thx for this.


  4. adnan zarif

    Hello,

    How can I update all zones ?
    I like to update all zones with CSV .

    Thank you


  5. Hi Adnan,

    For multiple zones there are a few ways to tackle it. You could also add a zone field into the CSV and modify the update process, or another way would be to handle the zone statically and loop through the update process. For cleanliness the CSV option is ideal.

    Sounds like a good chance for a part 2 :)

    Thanks…Eric


  6. Paul

    Is there a way we can add entries for the parent domain? In the GUI, if you leave the A record host blank, it defaults to ‘(same as parent)’. I have tried leaving this field blank in the CSV and entering ‘(same as parent)’. Neither of these worked.

    P.S. Thanks for the script, very useful.


  7. Kursad Olmez

    Hi Eric,

    Thanks for the great script. This will save me a lot of work.
    I would like to know is it possible to replace and add blank records?

    I have a two (same as parent folder) Blank records. One of them is Host (A) record and the other one is TXT (for SPF usage) record.

    I created a csv file like this;

    zone,name,type,address
    fqdn.domain.name,www,A,111.222.333.444
    fqdn.domain.name,mail,A,111.222.333.444
    fqdn.domain.name,ftp,A,111.222.333.444
    fqdn.domain.name,,A,111.222.333.444
    fqdn.domain.name,,TXT,v=spf1 a mx ip4:111.222.333.444 -all

    But when I run the script it updates records except the name field left blank.

    How do I update these blank ones?

    Thank you.


  8. laobing

    It is useful for me ,thanks a lot.


  9. [...] an earlier post on the site (Microsoft DNS record updates using PowerShell and DNSCMD) I noted how PowerShell cannot natively update records in MS DNS, however we could leverage the [...]


  10. Hi Paul,

    I’m so sorry for the super late reply on this. I’ve adjusted the script in a second post which you can find here:

    http://www.discoposse.com/index.php/2013/04/14/updating-same-as-parent-folder-records-with-dnscmd-and-powershell/

    That will allow for the (same as parent) records. In that post it refers to NS records, but any records with the blank name which creates it as (same as parent) will be applicable.

    Thanks!

    Eric


  11. Hi Kursad,

    Thank you for bringing this issue up for me. I believe that it’s been sorted out with an update that I’ve just posted here:

    http://www.discoposse.com/index.php/2013/04/14/updating-same-as-parent-folder-records-with-dnscmd-and-powershell/

    The blank records which create a (Same as parent folder) record will be corrected with the updated script. I’m going to put additional notes in this post also.

    Thanks!

    Eric



Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>