Administering Microsoft DNS in PowerShell

DNS administration in PowerShell, including tasks like creating zones and adding Host (A) records, can be performed using the WMI interface. Full documentation for the interface is available from Microsoft in the DNS WMI Provider Reference.

I have released a PowerShell 2.0 module using the WMI provider here.

There are a few limitations of the interface. The properties associated with Aging are read-only and cannot be set. Several of the configuration options are not available including the option to enable GlobalNames with Windows Server 2008.

Common variables

The examples below use two common variables. Both should be updated to reflect the environment used to execute any command.

$ServerName = "dns01" $ContainerName = "domain.example"

Management Class vs Management Object

Two different classes from the .NET Framework are used below. The ManagementObject, created using Get-WMIObject, and the ManagementClass created using [WMIClass].

[WMIClass] creates the same object as the following example.

$Scope = New-Object Management.ManagementScope("$ServerNamerootMicrosoftDNS") $Path = New-Object Management.ManagementPath("MicrosoftDNS_Zone") $Options = New-Object Management.ObjectGetOptions($Null, [System.TimeSpan]::MaxValue, $True) $ZoneClass = New-Object Management.ManagementClass($Scope, $Path, $Options)

In general terms, to change something that already exists use the properties and methods of a ManagementObject via Get-WMIObject. To add something new use the methods associated with a ManagementClass.

Creating an instance of a Management Object

$Zones = Get-WMIObject MicrosoftDNS_Zone -Namespace "rootMicrosoftDNS" -Computer $ServerName

Exploring the Management Object

Showing the object type:
[code lang=”plain”]
PS C:> $Zones.GetType()

IsPublic IsSerial Name BaseType
——– ——– —- ——–
True True Object[] System.Array

Showing the properties and methods:
[code lang=”plain”]
PS C:> $Zones | Get-Member

TypeName: System.Management.ManagementObject#rootMicrosoftDNSMicrosoftDNS_Zone

Name MemberType Definition
—- ———- ———-
AgeAllRecords Method Management.ManagementBaseObject AgeAllRec…
ChangeZoneType Method Management.ManagementBaseObject ChangeZon…
ForceRefresh Method Management.ManagementBaseObject ForceRefr…
GetDistinguishedName Method Management.ManagementBaseObject GetDistin…
PauseZone Method Management.ManagementBaseObject PauseZone()
ReloadZone Method Management.ManagementBaseObject ReloadZone()
ResetSecondaries Method Management.ManagementBaseObject ResetSeco…
ResumeZone Method Management.ManagementBaseObject ResumeZone()
UpdateFromDS Method Management.ManagementBaseObject UpdateFro…
WriteBackZone Method Management.ManagementBaseObject WriteBack…
Aging Property Boolean Aging {get;set;}
AllowUpdate Property UInt32 AllowUpdate {get;set;}
AutoCreated Property Boolean AutoCreated {get;set;}
AvailForScavengeTime Property UInt32 AvailForScavengeTime {get;set;}
Caption Property String Caption {get;set;}
ContainerName Property String ContainerName {get;set;}
DataFile Property String DataFile {get;set;}
Description Property String Description {get;set;}
DisableWINSRecordReplicat Property Boolean DisableWINSRecordReplication {ge…
DnsServerName Property String DnsServerName {get;set;}
DsIntegrated Property Boolean DsIntegrated {get;set;}
ForwarderSlave Property Boolean ForwarderSlave {get;set;}
ForwarderTimeout Property UInt32 ForwarderTimeout {get;set;}
InstallDate Property String InstallDate {get;set;}
LastSuccessfulSoaCheck Property UInt32 LastSuccessfulSoaCheck {get;set;}
LastSuccessfulXfr Property UInt32 LastSuccessfulXfr {get;set;}
LocalMasterServers Property String[] LocalMasterServers {get;set;}
MasterServers Property String[] MasterServers {get;set;}
Name Property String Name {get;set;}
NoRefreshInterval Property UInt32 NoRefreshInterval {get;set;}
Notify Property UInt32 Notify {get;set;}
NotifyServers Property String[] NotifyServers {get;set;}
Paused Property Boolean Paused {get;set;}
RefreshInterval Property UInt32 RefreshInterval {get;set;}
Reverse Property Boolean Reverse {get;set;}
ScavengeServers Property String[] ScavengeServers {get;set;}
SecondaryServers Property String[] SecondaryServers {get;set;}
SecureSecondaries Property UInt32 SecureSecondaries {get;set;}
Shutdown Property Boolean Shutdown {get;set;}
Status Property String Status {get;set;}
UseNBStat Property Boolean UseNBStat {get;set;}
UseWins Property Boolean UseWins {get;set;}
ZoneType Property UInt32 ZoneType {get;set;}

Showing a subset of the properties within the object:
[code lang=”plain”]
PS C:> $Zones | Select-Object Name, DsIntegrated, ZoneType, Reverse

Name DsIntegrated ZoneType Reverse
—- ———— ——– ——- False 1 True False 1 True False 1 True

Creating an instance of a Management Class

$ZoneClass = [WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone"

Exploring the Management Class

Showing the object type:
[code lang=”plain”]
PS C:> $ZoneClass.GetType()

IsPublic IsSerial Name BaseType
——– ——– —- ——–
True True ManagementClass System.Management.ManagementObject

Showing the properties and methods:
[code lang=”plain”]
PS C:> $ZoneClass | Get-Member

TypeName: System.Management.ManagementClass#ROOTMicrosoftDNSMicrosoftDNS_Zone

Name MemberType Definition
—- ———- ———-
Name AliasProperty Name = __Class
CreateZone Method System.Management.ManagementBaseObject CreateZone(Sys…

Listing the parameters required for a method

The output above truncates the strings detailing the parameters used for each method. The following shows how the full list can be displayed.

([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_AType") | Get-Member -Name CreateInstanceFromPropertyData | Format-List

Note that while this shows the parameter type it does not show whether or not the parameter is required or optional. For full details refer to the DNS WMI Provider Reference.

Creating Zones

The following values represent the Zone Types available with Microsoft DNS.
[code lang=”plain”]
0 Primary zone
1 Secondary zone
2 Stub zone

  • Windows Server 2003: This zone type is introduced in Windows Server 2003.
    3 Zone forwarder
  • Windows Server 2003: This zone type is introduced in Windows Server 2003.

Create a Forward or Reverse Lookup Zone

This example shows all of the possible parameters, this can be reduced to a single line by dropping the comments and use of variables. Note that any optional variable can be set to $Null or “”.

Forward Lookup zone name (example) $Name = "domain.example" # Reverse Lookup zone name (example for 1.2.3.x Subnet) $Name = "" # See above $Type = 0 # AD Integration (only valid on Active Directory Domain Controllers) $IsDSIntegrated = $False # FileName (Optional and only valid for zones with AD integrated set to $False) # File must exist if specified and have size greater than 0b. $Filename = $Null # Master IP (Optional and only valid for Secondary, Stub and Forwarder zones) $MasterIP = $Null # AdminEmail (Optional and only valid for Primary zones, writes into SOA record) $AdminEmail = $Null $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( $Name, $Type, $IsDSIntegrated, $FileName, $MasterIP, $AdminEmail)


New Standard Primary Forward Lookup Zone $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( "standardprimary.example", 0, $False) # New Standard Primary Forward Lookup Zone using existing zone file $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( "standardprimary-existing.example", 0, $False, "standardprimary-existing.example.dns") # New Active Directory Integrated Forward Lookup Zone $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( "adprimary.example", 0, $True) # New Standard Primary Reverse Lookup Zone $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( "", 0) # New Active Directory Integrated Reverse Lookup Zone $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( "", 0, $True) # New Secondary Forward Lookup Zone $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( "standardsecondary.example", 1, $False, "", @("", "")) # New Stub Zone $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( "stub.example", 2, $False, "", @("", "")) # New Conditional Forwarder $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( "conditionalforwarder.example", 3, $False, "", @("", "")) # New AD Integrated Conditional Forwarder $NewZone = ([WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_Zone").CreateZone( "adconditionalforwarder.example", 3, $True, "", @("", ""))

Creating resource records with CreateInstanceFromPropertyData

CreateInstanceFromPropertyData is available on each individual record class. For example, the method can be invoked from MicrosoftDNS_AType, or MicrosoftDNS_MXType, and so on. Note that the syntax for the method varies slightly depending on the record type.

Create an A record

Record Name (Owner Name). Should include full suffix to prevent the method # throwing an error. $OwnerName = "www.$ContainerName" # Class, as in IN, CS, CH or HS. Normally only care about IN (Internet: 1) which # is the default. (Optional) $RecordClass = $Null # Time To Live in seconds (Optional) $TTL = $Null # IP Address is required $IPAddress = "" $NewATypeClass = [WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_AType" $NewARecord = $NewATypeClass.CreateInstanceFromPropertyData( $ServerName, $ContainerName, $OwnerName, $RecordClass, $TTL, $IPAddress)

Create an MX record

Record Name (Owner Name). Normally the SMTP domain, in this case it matches # ContainerName. $OwnerName = $ContainerName $RecordClass = $Null $TTL = $Null # Preference, numeric value used to determine the preferred server(s) $Preference = 10 # The server used to handle the mail $MailExchange = "mail.domain.example" $NewMXTypeClass = [WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_MXType" $NewMXRecord = $NewMXTypeClass.CreateInstanceFromPropertyData( $ServerName, $ContainerName, $OwnerName, $RecordClass, $TTL, $Preference, $MailExchange)

Creating resource records with CreateInstanceFromTextRepresentation

CreateInstanceFromTextRepresentation is available from the MicrosoftDNS_ResourceRecord class. It takes fewer parameters than the previous method but ultimately requires exactly the same information.

Create an NS record

The text version of the record. Must include Class (IN) or this will fail. # @ represents the origin, or zone / domain name. $TextRepresentation = "@ IN NS" $NewRRClass = [WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_ResourceRecord" $NewRR = $NewRRClass.CreateInstanceFromTextRepresentation( $ServerName, $ContainerName, $TextRepresentation)

Create a TXT record

Using @ with the TXT record here will cause an error when executing the method. # Instead, this uses the $ContainerName variable. # Unlike the zone file itself the method does not require a terminating # period following each name. $TextRepresentation = "$ContainerName IN TXT "hello world"" $NewRRClass = [WMIClass]"$ServerNamerootMicrosoftDNS:MicrosoftDNS_ResourceRecord" $NewRR = $NewRRClass.CreateInstanceFromTextRepresentation( $ServerName, $ContainerName, $TextRepresentation)

Update server data file

DNS zones are held in memory, any change to the zone is performed in memory rather than as a direct alteration of the zone file. The following method can be used to force the updated zone to write back to the file.

(Get-WMIObject MicrosoftDNS_Zone -Namespace "rootMicrosoftDNS" -Computer $ServerName ` -Filter "ContainerName='$ContainerName'").WriteBackZone()

Reload a zone

Changes made to the zone file can be loaded into memory immediately using the ReloadZone method.

(Get-WMIObject MicrosoftDNS_Zone -Namespace "rootMicrosoftDNS" -Computer $ServerName ` -Filter "ContainerName='$ContainerName'").ReloadZone()

Enabling and starting scavenging on a server

Enabling scavenging requires setting the ScavengingInterval property to a non-zero value. The value representing the interval uses Hours.

Connecting to the Server Management Object $Server = Get-WMIObject MicrosoftDNS_Server -Namespace "rootMicrosoftDNS" -Computer $ServerName # Setting a new Scavenging Interval $Server.ScavengingInterval = 24 $Server.Put() # Start Scavenging $Server.StartScavenging()

Clear the cache

Any cached entries on a server can be cleared using the ClearCache method of the MicrosoftDNS_Cache class.

(Get-WMIObject MicrosoftDNS_Cache -Namespace "rootMicrosoftDNS" -Computer $ServerName).ClearCache()

Displaying the DNS server statistics

Each DNS server holds a variety of statistics that can help to evaluate server performance.

Get-WMIObject MicrosoftDNS_Statistic -Namespace "rootMicrosoftDNS" -Computer $ServerName | Select-Object Name, StringValue, Value