Search code examples
.netwindowsdns

Is there a .NET interface to edit Windows DNS Server zones?


I think I may need to create a tool to assist in migrating DNS information, creating "shadow" zones for NAT'ed addreses, and so on in our forest of 2003 and 2008 servers.

I know there are ways to access Windows DNS via WMI (and thus through PowerShell, WSH, etc., but are there better high-level options for .NET?

I would consider more flexible languages (e.g. Python) and libraries (e.g. BIND) except for the requirement of Microsoft's "secure updates".


Solution

  • Does the following post help you out at all? It gives some code to handle talking to the MS DNS server.

    http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/d7af771b-7c6b-4ee8-acfb-28a12bc1c5e7/

    Pasting their C# below for ease of reference. Note that if you run this code locally on the DNS itself, then you need to remove the authentication credentials portions below when calling this code... (i.e. DnsProvider dns = new DnsProvider("localhost",null,null);)

    using System;
    using System.Management;
    namespace DNS
    {
    public class DnsProvider
    {
    #region Members
    private ManagementScope Session=null;
    public string Server=null;
    public string User=null;
    private string Password=null;
    private string m_NameSpace=null;
    #endregion
    public DnsProvider(string serverName,string userName,string password)
    {
    this.Server=serverName;
    this.User=userName;
    this.Password=password;
    this.Logon();
    this.Initialize();
    }
    private void Logon()
    {
    this.m_NameSpace="\\\\" + this.Server + "\\root\\microsoftdns";
    ConnectionOptions con=new ConnectionOptions();
    con.Username=this.User;
    con.Password=this.Password;
    con.Impersonation=ImpersonationLevel.Impersonate;
    this.Session=new ManagementScope(this.NameSpace);
    this.Session.Options=con;
    this.Session.Connect();
    }
    private void Initialize()
    {
    }
    #region Methods
    public void Dispose()
    {
    }
    public void Dispose(ref ManagementClass x)
    {
    if(x!=null)
    {
    x.Dispose();
    x=null;
    }
    }
    public void Dispose(ref ManagementBaseObject x)
    {
    if(x!=null)
    {
    x.Dispose();
    x=null;
    }
    }
    public bool DomainExists(string domainName)
    {
    bool retval=false;
    string wql="";
    wql="SELECT *";
    wql+=" FROM MicrosoftDNS_ATYPE";
    wql+=" WHERE OwnerName = '" + domainName + "'";
    ObjectQuery q=new ObjectQuery(wql);
    ManagementObjectSearcher s=new ManagementObjectSearcher(this.Session,q);
    ManagementObjectCollection col=s.Get();
    int total=col.Count;
    foreach(ManagementObject o in col)
    {
    retval=true;
    }
    return retval;
    }
    public void AddDomain(string domainName,string ipDestination)
    {
    //check if domain already exists
    if(this.DomainExists(domainName))
    {
    throw new Exception("The domain you are trying to add already exists on this server!");
    }
    //generate zone
    ManagementClass man=this.Manage("MicrosoftDNS_Zone");
    ManagementBaseObject ret=null;
    ManagementBaseObject obj=man.GetMethodParameters("CreateZone");
    obj["ZoneName"]=domainName;
    obj["ZoneType"]=0;
    //invoke method, dispose unneccesary vars
    man.InvokeMethod("CreateZone",obj,null);
    this.Dispose(ref obj);
    this.Dispose(ref ret);
    this.Dispose(ref man);
    //add rr containing the ip destination
    this.AddARecord(domainName,null,ipDestination);
    }
    public void RemoveDomain(string domainName)
    {
    string wql="";
    wql="SELECT *";
    wql+=" FROM MicrosoftDNS_Zone";
    wql+=" WHERE Name = '" + domainName + "'";
    ObjectQuery q=new ObjectQuery(wql);
    ManagementObjectSearcher s=new ManagementObjectSearcher(this.Session,q);
    ManagementObjectCollection col=s.Get();
    int total=col.Count;
    foreach(ManagementObject o in col)
    {
    o.Delete();
    }
    }
    public void AddARecord(string domain,string recordName,string ipDestination)
    {
    if(this.DomainExists(recordName + "." + domain))
    {
    throw new Exception("That record already exists!");
    }
    ManagementClass man=new ManagementClass(this.Session,new ManagementPath("MicrosoftDNS_ATYPE"),null);
    ManagementBaseObject vars=man.GetMethodParameters("CreateInstanceFromPropertyData");
    vars["DnsServerName"]=this.Server;
    vars["ContainerName"]=domain;
    if(recordName==null)
    {
    vars["OwnerName"]=domain;
    }
    else
    {
    vars["OwnerName"]=recordName + "." + domain;
    }
    vars["IPAddress"]=ipDestination;
    man.InvokeMethod("CreateInstanceFromPropertyData",vars,null);
    }
    public void RemoveARecord(string domain,string aRecord)
    {
    string wql="";
    wql="SELECT *";
    wql+=" FROM MicrosoftDNS_ATYPE";
    wql+=" WHERE OwnerName = '" + aRecord + "." + domain + "'";
    ObjectQuery q=new ObjectQuery(wql);
    ManagementObjectSearcher s=new ManagementObjectSearcher(this.Session,q);
    ManagementObjectCollection col=s.Get();
    int total=col.Count;
    foreach(ManagementObject o in col)
    {
    o.Delete();
    }
    }
    #endregion
    #region Properties
    public string NameSpace
    {
    get
    {
    return this.m_NameSpace;
    }
    }
    public bool Enabled
    {
    get
    {
    bool retval=false;
    try
    {
    SelectQuery wql=new SelectQuery();
    wql.QueryString="";
    }
    catch
    {}
    return retval;
    }
    }
    public ManagementClass Manage(string path)
    {
    //ManagementClass retval=new ManagementClass(path);
    ManagementClass retval=new ManagementClass(this.Session,new ManagementPath(path),null);
    return retval;
    }
    #endregion
    }
    }