diff --git a/WebsitePanel/Lib/Microsoft.Management.Infrastructure.dll b/WebsitePanel/Lib/Microsoft.Management.Infrastructure.dll
new file mode 100644
index 00000000..9c72405b
Binary files /dev/null and b/WebsitePanel/Lib/Microsoft.Management.Infrastructure.dll differ
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/DnsCommands.cs b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/DnsCommands.cs
new file mode 100644
index 00000000..a82af726
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/DnsCommands.cs
@@ -0,0 +1,287 @@
+using System;
+using System.Linq;
+using System.Management.Automation;
+using System.Management.Automation.Runspaces;
+using System.Net;
+using WebsitePanel.Server.Utils;
+
+namespace WebsitePanel.Providers.DNS
+{
+ /// This class wraps MS DNS server PowerShell commands used by the WebsitePanel.
+ internal static class DnsCommands
+ {
+ /// Add parameter to PS command
+ /// command
+ /// Parameter name
+ /// Parameter value
+ /// Same command
+ private static Command addParam( this Command cmd, string name, object value )
+ {
+ cmd.Parameters.Add( name, value );
+ return cmd;
+ }
+
+ /// Add parameter without value to the PS command
+ /// command
+ /// Parameter name
+ /// Same command
+ private static Command addParam( this Command cmd, string name )
+ {
+ cmd.Parameters.Add( name );
+ return cmd;
+ }
+
+ /// Create "Where-Object -Property ... -eq -Value ..." command
+ ///
+ ///
+ ///
+ private static Command where( string property, object value )
+ {
+ return new Command( "Where-Object" )
+ .addParam( "Property", property )
+ .addParam( "eq" )
+ .addParam( "Value", value );
+ }
+
+ /// Test-DnsServer -IPAddress 127.0.0.1
+ /// PowerShell host to use
+ /// true if localhost is an MS DNS server
+ public static bool Test_DnsServer( this PowerShellHelper ps )
+ {
+ if( null == ps )
+ throw new ArgumentNullException( "ps" );
+
+ var cmd = new Command( "Test-DnsServer" )
+ .addParam( "IPAddress", IPAddress.Loopback );
+
+ PSObject res = ps.RunPipeline( cmd ).FirstOrDefault();
+
+ if( null == res || null == res.Properties )
+ return false;
+ PSPropertyInfo p = res.Properties[ "Result" ];
+ if( null == p || null == p.Value )
+ return false;
+ return p.Value.ToString() == "Success";
+ }
+
+ #region Zones
+
+ /// Get-DnsServerZone | Select-Object -Property ZoneName
+ /// Only primary DNS zones are returned
+ /// Array of zone names
+ public static string[] Get_DnsServerZone_Names( this PowerShellHelper ps )
+ {
+ var allZones = ps.RunPipeline( new Command( "Get-DnsServerZone" ),
+ where( "IsAutoCreated", false ) );
+
+ string[] res = allZones
+ .Select( pso => new
+ {
+ name = (string)pso.Properties[ "ZoneName" ].Value,
+ type = (string)pso.Properties[ "ZoneType" ].Value
+ } )
+ .Where( obj => obj.type == "Primary" )
+ .Select( obj => obj.name )
+ .ToArray();
+
+ Log.WriteInfo( "Get_DnsServerZone_Names: {{{0}}}", String.Join( ", ", res ) );
+ return res;
+ }
+
+ /// Returns true if the specified zone exists.
+ /// The PS pipeline being run: Get-DnsServerZone | Where-Object -Property ZoneName -eq -Value "name"
+ ///
+ ///
+ ///
+ public static bool ZoneExists( this PowerShellHelper ps, string name )
+ {
+ Log.WriteStart( "ZoneExists {0}", name );
+ bool res = ps.RunPipeline( new Command( "Get-DnsServerZone" ),
+ where( "ZoneName", name ) )
+ .Any();
+ Log.WriteEnd( "ZoneExists: {0}", res );
+ return res;
+ }
+
+ /* public enum eReplicationScope: byte
+ {
+ Custom, Domain, Forest, Legacy
+ } */
+
+ ///
+ ///
+ ///
+ /// Specifies a partition on which to store an Active Directory-integrated zone.
+ ///
+ public static void Add_DnsServerPrimaryZone( this PowerShellHelper ps, string zoneName, string[] secondaryServers )
+ {
+ Log.WriteStart( "Add_DnsServerPrimaryZone {0} {{{1}}}", zoneName, String.Join( ", ", secondaryServers ) );
+
+ // Add-DnsServerPrimaryZone -Name zzz.com -ZoneFile zzz.com.dns
+ var cmd = new Command( "Add-DnsServerPrimaryZone" );
+ cmd.addParam( "Name", zoneName );
+ cmd.addParam( "ZoneFile", zoneName + ".dns" );
+ ps.RunPipeline( cmd );
+
+ // Set-DnsServerPrimaryZone -Name zzz.com -SecureSecondaries ... -Notify ... Servers ..
+ cmd = new Command( "Set-DnsServerPrimaryZone" );
+ cmd.addParam( "Name", zoneName );
+
+ if( secondaryServers == null || secondaryServers.Length == 0 )
+ {
+ // transfers are not allowed
+ // inParams2[ "SecureSecondaries" ] = 3;
+ // inParams2[ "Notify" ] = 0;
+ cmd.addParam( "SecureSecondaries", "NoTransfer" );
+ cmd.addParam( "Notify", "NoNotify" );
+ }
+ else if( secondaryServers.Length == 1 && secondaryServers[ 0 ] == "*" )
+ {
+ // allowed transfer from all servers
+ // inParams2[ "SecureSecondaries" ] = 0;
+ // inParams2[ "Notify" ] = 1;
+ cmd.addParam( "SecureSecondaries", "TransferAnyServer" );
+ cmd.addParam( "Notify", "Notify" );
+ }
+ else
+ {
+ // allowed transfer from specified servers
+ // inParams2[ "SecureSecondaries" ] = 2;
+ // inParams2[ "SecondaryServers" ] = secondaryServers;
+ // inParams2[ "NotifyServers" ] = secondaryServers;
+ // inParams2[ "Notify" ] = 2;
+ cmd.addParam( "SecureSecondaries", "TransferToSecureServers" );
+ cmd.addParam( "Notify", "NotifyServers" );
+ cmd.addParam( "SecondaryServers", secondaryServers );
+ cmd.addParam( "NotifyServers", secondaryServers );
+ }
+ ps.RunPipeline( cmd );
+ Log.WriteEnd( "Add_DnsServerPrimaryZone" );
+ }
+
+ public static void Add_DnsServerSecondaryZone( this PowerShellHelper ps, string zoneName, string[] masterServers )
+ {
+ // Add-DnsServerSecondaryZone -Name zzz.com -ZoneFile zzz.com.dns
+ var cmd = new Command( "Add-DnsServerSecondaryZone" );
+ cmd.addParam( "Name", zoneName );
+ cmd.addParam( "ZoneFile", zoneName + ".dns" );
+ ps.RunPipeline( cmd );
+
+ // Set-DnsServerSecondaryZone -Name zzz.com -MasterServers ...
+ cmd = new Command( "Set-DnsServerSecondaryZone" );
+ cmd.addParam( "Name", zoneName );
+ cmd.addParam( "MasterServers", masterServers );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Remove_DnsServerZone( this PowerShellHelper ps, string zoneName )
+ {
+ var cmd = new Command( "Remove-DnsServerZone" );
+ cmd.addParam( "Name", zoneName );
+ cmd.addParam( "Force" );
+ ps.RunPipeline( cmd );
+ }
+ #endregion
+
+ /// Get all records, except the SOA
+ ///
+ /// Name of the zone
+ /// Array of records
+ public static DnsRecord[] GetZoneRecords( this PowerShellHelper ps, string zoneName )
+ {
+ // Get-DnsServerResourceRecord -ZoneName xxxx.com
+ var allRecords = ps.RunPipeline( new Command( "Get-DnsServerResourceRecord" ).addParam( "ZoneName", zoneName ) );
+
+ return allRecords.Select( o => o.asDnsRecord( zoneName ) )
+ .Where( r => null != r )
+ .Where( r => r.RecordType != DnsRecordType.SOA )
+ // .Where( r => !( r.RecordName == "@" && DnsRecordType.NS == r.RecordType ) )
+ .ToArray();
+ }
+
+ #region Records add / remove
+
+ public static void Add_DnsServerResourceRecordA( this PowerShellHelper ps, string zoneName, string Name, string address )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecordA" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "IPv4Address", address );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordAAAA( this PowerShellHelper ps, string zoneName, string Name, string address )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecordAAAA" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "IPv6Address", address );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordCName( this PowerShellHelper ps, string zoneName, string Name, string alias )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecordCName" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "HostNameAlias", alias );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordMX( this PowerShellHelper ps, string zoneName, string Name, string mx, UInt16 pref )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecordMX" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "MailExchange", mx );
+ cmd.addParam( "Preference", pref );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordNS( this PowerShellHelper ps, string zoneName, string Name, string NameServer )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecord" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "NS" );
+ cmd.addParam( "NameServer", NameServer );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordTXT( this PowerShellHelper ps, string zoneName, string Name, string txt )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecord" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "Txt" );
+ cmd.addParam( "DescriptiveText", txt );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Add_DnsServerResourceRecordSRV( this PowerShellHelper ps, string zoneName, string Name, string DomainName, UInt16 Port, UInt16 Priority, UInt16 Weight )
+ {
+ var cmd = new Command( "Add-DnsServerResourceRecord" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "Srv" );
+ cmd.addParam( "DomainName", DomainName );
+ cmd.addParam( "Port", Port );
+ cmd.addParam( "Priority", Priority );
+ cmd.addParam( "Weight", Weight );
+ ps.RunPipeline( cmd );
+ }
+
+ public static void Remove_DnsServerResourceRecord( this PowerShellHelper ps, string zoneName, string Name, string type )
+ {
+ // Remove-DnsServerResourceRecord -ZoneName xxxx.com -Name "@" -RRType Soa -Force
+ var cmd = new Command( "Remove-DnsServerResourceRecord" );
+ cmd.addParam( "ZoneName", zoneName );
+ cmd.addParam( "Name", Name );
+ cmd.addParam( "RRType", type );
+ cmd.addParam( "Force" );
+ ps.RunPipeline( cmd );
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/MsDNS.cs b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/MsDNS.cs
new file mode 100644
index 00000000..9dfa9f69
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/MsDNS.cs
@@ -0,0 +1,424 @@
+// Copyright (c) 2012, Outercurve Foundation.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// - Neither the name of the Outercurve Foundation nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// A lot of modifications made since 2012..
+
+using System;
+using System.Management;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Win32;
+
+using WebsitePanel.Server.Utils;
+using WebsitePanel.Providers.Utils;
+
+namespace WebsitePanel.Providers.DNS
+{
+ public class MsDNS: HostingServiceProviderBase, IDnsServer
+ {
+
+ protected int ExpireLimit
+ {
+ get { return ProviderSettings.GetInt( "ExpireLimit" ); }
+ }
+
+ protected int MinimumTTL
+ {
+ get { return ProviderSettings.GetInt( "MinimumTTL" ); }
+ }
+
+ protected int RefreshInterval
+ {
+ get { return ProviderSettings.GetInt( "RefreshInterval" ); }
+ }
+
+ protected int RetryDelay
+ {
+ get { return ProviderSettings.GetInt( "RetryDelay" ); }
+ }
+
+ protected bool AdMode
+ {
+ get { return ProviderSettings.GetBool( "AdMode" ); }
+ }
+
+ private PowerShellHelper ps = null;
+ private WmiHelper wmi = null; //< We still need WMI because PowerShell doesn't support SOA updates.
+ private bool bulkRecords;
+
+ public MsDNS()
+ {
+ // Create PowerShell helper
+ ps = new PowerShellHelper();
+ if( !this.IsInstalled() )
+ return;
+
+ // Create WMI helper
+ wmi = new WmiHelper( "root\\MicrosoftDNS" );
+ }
+
+ #region Zones
+
+ public virtual string[] GetZones()
+ {
+ return ps.Get_DnsServerZone_Names();
+ }
+
+ public virtual bool ZoneExists( string zoneName )
+ {
+ return ps.ZoneExists( zoneName );
+ }
+
+ public virtual DnsRecord[] GetZoneRecords( string zoneName )
+ {
+ return ps.GetZoneRecords( zoneName );
+ }
+
+ public virtual void AddPrimaryZone( string zoneName, string[] secondaryServers )
+ {
+ ps.Add_DnsServerPrimaryZone( zoneName, secondaryServers );
+
+ // delete orphan NS records
+ DeleteOrphanNsRecords( zoneName );
+ }
+
+ public virtual void AddSecondaryZone( string zoneName, string[] masterServers )
+ {
+ ps.Add_DnsServerSecondaryZone( zoneName, masterServers );
+
+ // delete orphan NS records
+ DeleteOrphanNsRecords( zoneName );
+ }
+
+ public virtual void DeleteZone( string zoneName )
+ {
+ try
+ {
+ ps.Remove_DnsServerZone( zoneName );
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( ex );
+ }
+ }
+
+ public virtual void AddZoneRecord( string zoneName, DnsRecord record )
+ {
+ try
+ {
+ string name = record.RecordName;
+ if( String.IsNullOrEmpty( name ) )
+ name = ".";
+
+ if( record.RecordType == DnsRecordType.A )
+ ps.Add_DnsServerResourceRecordA( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.AAAA )
+ ps.Add_DnsServerResourceRecordAAAA( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.CNAME )
+ ps.Add_DnsServerResourceRecordCName( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.MX )
+ ps.Add_DnsServerResourceRecordMX( zoneName, name, record.RecordData, (ushort)record.MxPriority );
+ else if( record.RecordType == DnsRecordType.NS )
+ ps.Add_DnsServerResourceRecordNS( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.TXT )
+ ps.Add_DnsServerResourceRecordTXT( zoneName, name, record.RecordData );
+ else if( record.RecordType == DnsRecordType.SRV )
+ ps.Add_DnsServerResourceRecordSRV( zoneName, name, record.RecordData, (ushort)record.SrvPort, (ushort)record.SrvPriority, (ushort)record.SrvWeight );
+ else
+ throw new Exception( "Unknown record type" );
+ }
+ catch( Exception ex )
+ {
+ // log exception
+ Log.WriteError( ex );
+ }
+ }
+
+ public virtual void AddZoneRecords( string zoneName, DnsRecord[] records )
+ {
+ bulkRecords = true;
+ try
+ {
+ foreach( DnsRecord record in records )
+ AddZoneRecord( zoneName, record );
+ }
+ finally
+ {
+ bulkRecords = false;
+ }
+
+ UpdateSoaRecord( zoneName );
+ }
+
+ public virtual void DeleteZoneRecord( string zoneName, DnsRecord record )
+ {
+ try
+ {
+ string rrType;
+ if( !RecordTypes.rrTypeFromRecord.TryGetValue( record.RecordType, out rrType ) )
+ throw new Exception( "Unknown record type" );
+ ps.Remove_DnsServerResourceRecord( zoneName, record.RecordName, rrType );
+ }
+ catch( Exception ex )
+ {
+ // log exception
+ Log.WriteError( ex );
+ }
+ }
+
+ public virtual void DeleteZoneRecords( string zoneName, DnsRecord[] records )
+ {
+ foreach( DnsRecord record in records )
+ DeleteZoneRecord( zoneName, record );
+ }
+
+ public void AddZoneRecord( string zoneName, string recordText )
+ {
+ try
+ {
+ Log.WriteStart( string.Format( "Adding MS DNS Server zone '{0}' record '{1}'", zoneName, recordText ) );
+ AddDnsRecord( zoneName, recordText );
+ Log.WriteEnd( "Added MS DNS Server zone record" );
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( ex );
+ throw;
+ }
+ }
+ #endregion
+
+ #region SOA Record
+ public virtual void UpdateSoaRecord( string zoneName, string host, string primaryNsServer, string primaryPerson )
+ {
+ host = CorrectHostName( zoneName, host );
+
+ // delete record if exists
+ DeleteSoaRecord( zoneName );
+
+ // format record data
+ string recordText = GetSoaRecordText( host, primaryNsServer, primaryPerson );
+
+ // add record
+ AddDnsRecord( zoneName, recordText );
+
+ // update SOA record
+ UpdateSoaRecord( zoneName );
+ }
+
+ private void DeleteSoaRecord( string zoneName )
+ {
+ // TODO: find a PowerShell replacement
+
+ string query = String.Format( "SELECT * FROM MicrosoftDNS_SOAType " +
+ "WHERE OwnerName = '{0}'",
+ zoneName );
+ using( ManagementObjectCollection objRRs = wmi.ExecuteQuery( query ) )
+ {
+ foreach( ManagementObject objRR in objRRs ) using( objRR )
+ objRR.Delete();
+ }
+
+ // This doesn't work: no errors in PS, but the record stays in the DNS
+ /* try
+ {
+ ps.Remove_DnsServerResourceRecord( zoneName, "@", "Soa" );
+ }
+ catch( System.Exception ex )
+ {
+ Log.WriteWarning( "{0}", ex.Message );
+ } */
+ }
+
+ private string GetSoaRecordText( string host, string primaryNsServer, string primaryPerson )
+ {
+ return String.Format( "{0} IN SOA {1} {2} 1 900 600 86400 3600", host, primaryNsServer, primaryPerson );
+ }
+
+ private static string RemoveTrailingDot( string str )
+ {
+ return ( str.EndsWith( "." ) ) ? str.Substring( 0, str.Length - 1 ) : str;
+ }
+
+ private void UpdateSoaRecord( string zoneName )
+ {
+ if( bulkRecords )
+ return;
+
+ // TODO: find a PowerShell replacement
+
+ // get existing SOA record in order to read serial number
+ try
+ {
+
+ ManagementObject objSoa = wmi.GetWmiObject( "MicrosoftDNS_SOAType", "ContainerName = '{0}'", RemoveTrailingDot( zoneName ) );
+
+ if( objSoa != null )
+ {
+ if( objSoa.Properties[ "OwnerName" ].Value.Equals( zoneName ) )
+ {
+ string primaryServer = (string)objSoa.Properties[ "PrimaryServer" ].Value;
+ string responsibleParty = (string)objSoa.Properties[ "ResponsibleParty" ].Value;
+ UInt32 serialNumber = (UInt32)objSoa.Properties[ "SerialNumber" ].Value;
+
+ // update record's serial number
+ string sn = serialNumber.ToString();
+ string todayDate = DateTime.Now.ToString( "yyyyMMdd" );
+ if( sn.Length < 10 || !sn.StartsWith( todayDate ) )
+ {
+ // build a new serial number
+ sn = todayDate + "01";
+ serialNumber = UInt32.Parse( sn );
+ }
+ else
+ {
+ // just increment serial number
+ serialNumber += 1;
+ }
+
+ // update SOA record
+ using( ManagementBaseObject methodParams = objSoa.GetMethodParameters( "Modify" ) )
+ {
+ methodParams[ "ResponsibleParty" ] = responsibleParty;
+ methodParams[ "PrimaryServer" ] = primaryServer;
+ methodParams[ "SerialNumber" ] = serialNumber;
+
+ methodParams[ "ExpireLimit" ] = ExpireLimit;
+ methodParams[ "MinimumTTL" ] = MinimumTTL;
+ methodParams[ "TTL" ] = MinimumTTL;
+ methodParams[ "RefreshInterval" ] = RefreshInterval;
+ methodParams[ "RetryDelay" ] = RetryDelay;
+
+ ManagementBaseObject outParams = objSoa.InvokeMethod( "Modify", methodParams, null );
+ }
+ //
+ objSoa.Dispose();
+ }
+
+ }
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( ex );
+ }
+ }
+
+ #endregion
+
+ private void DeleteOrphanNsRecords( string zoneName )
+ {
+ // TODO: find a PowerShell replacement
+ string machineName = System.Net.Dns.GetHostEntry( "LocalHost" ).HostName.ToLower();
+ string computerName = Environment.MachineName.ToLower();
+
+ using( ManagementObjectCollection objRRs = wmi.ExecuteQuery( String.Format( "SELECT * FROM MicrosoftDNS_NSType WHERE DomainName = '{0}'", zoneName ) ) )
+ {
+ foreach( ManagementObject objRR in objRRs )
+ {
+ using( objRR )
+ {
+ string ns = ( (string)objRR.Properties[ "NSHost" ].Value ).ToLower();
+ if( ns.StartsWith( machineName ) || ns.StartsWith( computerName ) )
+ objRR.Delete();
+
+ }
+ }
+ }
+ }
+
+ #region private helper methods
+
+ private string GetDnsServerName()
+ {
+ // TODO: find a PowerShell replacement
+ using( ManagementObject objServer = wmi.GetObject( "MicrosoftDNS_Server.Name=\".\"" ) )
+ {
+ return (string)objServer.Properties[ "Name" ].Value;
+ }
+ }
+
+ private string AddDnsRecord( string zoneName, string recordText )
+ {
+ // get the name of the server
+ string serverName = GetDnsServerName();
+
+ // TODO: find a PowerShell replacement
+ // add record
+ using( ManagementClass clsRR = wmi.GetClass( "MicrosoftDNS_ResourceRecord" ) )
+ {
+ object[] prms = new object[] { serverName, zoneName, recordText, null };
+ clsRR.InvokeMethod( "CreateInstanceFromTextRepresentation", prms );
+ return (string)prms[ 3 ];
+ }
+ }
+
+ private string CorrectHostName( string zoneName, string host )
+ {
+ // if host is empty or null
+ if( host == null || host == "" )
+ return zoneName;
+
+ // if there are not dot at all
+ else if( host.IndexOf( "." ) == -1 )
+ return host + "." + zoneName;
+
+ // if only one dot at the end
+ else if( host[ host.Length - 1 ] == '.' && host.IndexOf( "." ) == ( host.Length - 1 ) )
+ return host + zoneName;
+
+ // other cases
+ else
+ return host;
+ }
+ #endregion
+
+ public override void DeleteServiceItems( ServiceProviderItem[] items )
+ {
+ foreach( ServiceProviderItem item in items )
+ {
+ if( item is DnsZone )
+ {
+ try
+ {
+ // delete DNS zone
+ DeleteZone( item.Name );
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( String.Format( "Error deleting '{0}' MS DNS zone", item.Name ), ex );
+ }
+ }
+ }
+ }
+
+ public override bool IsInstalled()
+ {
+ return ps.Test_DnsServer();
+ }
+ }
+}
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/PowerShellHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/PowerShellHelper.cs
new file mode 100644
index 00000000..980e5ac7
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.DNS.MsDNS2012/PowerShellHelper.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Management.Automation;
+using System.Management.Automation.Runspaces;
+using WebsitePanel.Server.Utils;
+
+namespace WebsitePanel.Providers.DNS
+{
+ /// This class is a generic helper hosting the PowerShell runtime.
+ /// It's probably a good idea to move to some utility module.
+ public class PowerShellHelper: IDisposable
+ {
+ private static InitialSessionState s_session = null;
+
+ static PowerShellHelper()
+ {
+ s_session = InitialSessionState.CreateDefault();
+ // s_session.ImportPSModule( new string[] { "FileServerResourceManager" } );
+ }
+
+ public PowerShellHelper()
+ {
+ Log.WriteStart( "PowerShellHelper::ctor" );
+
+ Runspace rs = RunspaceFactory.CreateRunspace( s_session );
+ rs.Open();
+ // rs.SessionStateProxy.SetVariable( "ConfirmPreference", "none" );
+
+ this.runSpace = rs;
+ Log.WriteEnd( "PowerShellHelper::ctor" );
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ if( this.runSpace == null )
+ return;
+ if( this.runSpace.RunspaceStateInfo.State == RunspaceState.Opened )
+ this.runSpace.Close();
+ this.runSpace = null;
+ }
+ catch( Exception ex )
+ {
+ Log.WriteError( "Runspace error", ex );
+ }
+ }
+
+ public Runspace runSpace { get; private set; }
+
+ public Collection RunPipeline( params Command[] pipelineCommands )
+ {
+ Log.WriteStart( "ExecuteShellCommand" );
+ List