diff --git a/CHANGELOG.md b/CHANGELOG.md index 46cc2d11..20e95f58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed code coverage in the pipeline ([issue #246](https://github.com/dsccommunity/DnsServerDsc/issues/246)). - ResourceBase - Added new method `Assert()` tha calls `Assert-Module` and `AssertProperties()`. +- DnsRecordNs + - Added new resource to manage NS records +- DnsRecordNsScoped + - Added new resource to manage scoped NS records ### Changed @@ -153,7 +157,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 (EDNS) settings ([issue #194](https://github.com/dsccommunity/DnsServerDsc/issues/194)). - xDNSServerClientSubnet - Added integration tests. -- xDnsServerPrimaryZone +- DnsServerPrimaryZone - Added integration tests ([issue #173](https://github.com/dsccommunity/DnsServerDsc/issues/173)). - Added more examples. - xDnsRecordMx @@ -227,7 +231,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 parameter `DnsServer`. This prevents the resource from being used twice in the same configuration using the same value for the parameter `DnsServer` ([issue #157](https://github.com/dsccommunity/DnsServerDsc/issues/157)). -- xDnsServerPrimaryZone +- DnsServerPrimaryZone - Now the property `Name` is always returned from `Get-TargetResource` since it is a `Key` property. - xDnsServerForwarder @@ -343,7 +347,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 master and dev branch ([issue #73](https://github.com/PowerShell/xActiveDirectory/issues/73)). - Updated description of resource module in README.md. - Added resource xDnsServerZoneAging. [Claudio Spizzi (@claudiospizzi)](https://github.com/claudiospizzi) -- Changes to xDnsServerPrimaryZone +- Changes to DnsServerPrimaryZone - Fix bug in Get-TargetResource that caused the Zone Name to be null ([issue #63](https://github.com/dsccommunity/DnsServerDsc/issues/63)). [Brandon Padgett (@gerane)](https://github.com/gerane) @@ -399,7 +403,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added Resource xDnsRecord with support for CNames. - This will replace xDnsARecord in a future release. -- Added **xDnsServerPrimaryZone** resource +- Added **DnsServerPrimaryZone** resource ## [1.4.0.0] - 2015-12-02 diff --git a/source/Classes/003.DnsRecordMx.ps1 b/source/Classes/003.DnsRecordMx.ps1 index 06f7c621..9ca32697 100644 --- a/source/Classes/003.DnsRecordMx.ps1 +++ b/source/Classes/003.DnsRecordMx.ps1 @@ -6,13 +6,13 @@ The DnsRecordMx DSC resource manages MX DNS records against a specific zone on a Domain Name System (DNS) server. .PARAMETER EmailDomain - Everything after the '@' in the email addresses supported by this mail exchanger. It must be a subdomain the zone or the zone itself. To specify all subdomains, use the '*' character (i.e.: *.contoso.com). (Key Parameter) + Everything after the '@' in the email addresses supported by this mail exchanger. It must be a subdomain the zone or the zone itself. To specify all subdomains, use the '*' character (i.e.: *.contoso.com). (Key Parameter) .PARAMETER MailExchange - FQDN of the server handling email for the specified email domain. When setting the value, this FQDN must resolve to an IP address and cannot reference a CNAME record. (Key Parameter) + FQDN of the server handling email for the specified email domain. When setting the value, this FQDN must resolve to an IP address and cannot reference a CNAME record. (Key Parameter) .PARAMETER Priority - Specifies the priority for this MX record among other MX records that belong to the same email domain, where a lower value has a higher priority. (Mandatory Parameter) + Specifies the priority for this MX record among other MX records that belong to the same email domain, where a lower value has a higher priority. (Mandatory Parameter) #> [DscResource()] diff --git a/source/Classes/003.DnsRecordNs.ps1 b/source/Classes/003.DnsRecordNs.ps1 new file mode 100644 index 00000000..58885735 --- /dev/null +++ b/source/Classes/003.DnsRecordNs.ps1 @@ -0,0 +1,162 @@ +<# + .SYNOPSIS + The DnsRecordNs DSC resource manages NS DNS records against a specific zone on a Domain Name System (DNS) server. + + .DESCRIPTION + The DnsRecordNs DSC resource manages NS DNS records against a specific zone on a Domain Name System (DNS) server. + + .PARAMETER DomainName + Specifies the fully qualified DNS domain name for which the NameServer is authoritative. It must be a subdomain the zone or the zone itself. To specify all subdomains, use the '*' character (i.e.: *.contoso.com). (Key Parameter) + + .PARAMETER NameServer + Specifies the name server of a domain. This should be a fully qualified domain name, not an IP address (Key Parameter) +#> + +[DscResource()] +class DnsRecordNs : DnsRecordBase +{ + [DscProperty(Key)] + [System.String] + $DomainName + + [DscProperty(Key)] + [System.String] + $NameServer + + [DnsRecordNs] Get() + { + return ([DnsRecordBase] $this).Get() + } + + [void] Set() + { + ([DnsRecordBase] $this).Set() + } + + [System.Boolean] Test() + { + return ([DnsRecordBase] $this).Test() + } + + [System.String] getRecordName() + { + $aRecordName = $null + + # Use regex matching to determine if the domain name provided is a subdomain of the ZoneName (ends in ZoneName). + $regexMatch = $this.DomainName | Select-String -Pattern "^((.*?)\.){0,1}$($this.ZoneName)`$" + + if ($null -eq $regexMatch) + { + throw ($this.localizedData.DomainZoneMismatch -f $this.DomainName, $this.ZoneName) + } + else + { + # Match group 2 contains the value in which we are interested. + $aRecordName = $regexMatch.Matches.Groups[2].Value + if ($aRecordName -eq '') + { + $aRecordName = '.' + } + } + return $aRecordName + } + + hidden [Microsoft.Management.Infrastructure.CimInstance] GetResourceRecord() + { + Write-Verbose -Message ($this.localizedData.GettingDnsRecordMessage -f 'Ns', $this.ZoneName, $this.ZoneScope, $this.DnsServer) + + $dnsParameters = @{ + ZoneName = $this.ZoneName + ComputerName = $this.DnsServer + RRType = 'NS' + } + + if ($this.isScoped) + { + $dnsParameters['ZoneScope'] = $this.ZoneScope + } + + $record = Get-DnsServerResourceRecord @dnsParameters -ErrorAction SilentlyContinue | Where-Object -FilterScript { + $translatedRecordName = $this.getRecordName() + if ($translatedRecordName -eq '.') + { + $translatedRecordName = '@' + } + $_.HostName -eq $translatedRecordName -and + $_.RecordData.NameServer -eq "$($this.NameServer)." + } + + return $record + } + + hidden [DnsRecordNs] NewDscResourceObjectFromRecord([Microsoft.Management.Infrastructure.CimInstance] $record) + { + $dscResourceObject = [DnsRecordNs] @{ + ZoneName = $this.ZoneName + DomainName = $this.DomainName + NameServer = $this.NameServer + TimeToLive = $record.TimeToLive.ToString() + DnsServer = $this.DnsServer + Ensure = 'Present' + } + + return $dscResourceObject + } + + hidden [void] AddResourceRecord() + { + $dnsParameters = @{ + ZoneName = $this.ZoneName + ComputerName = $this.DnsServer + NS = $true + Name = $this.getRecordName() + NameServer = $this.NameServer + } + + if ($this.isScoped) + { + $dnsParameters['ZoneScope'] = $this.ZoneScope + } + + if ($null -ne $this.TimeToLive) + { + $dnsParameters.Add('TimeToLive', $this.TimeToLive) + } + + Write-Verbose -Message ($this.localizedData.CreatingDnsRecordMessage -f 'NS', $this.ZoneName, $this.ZoneScope, $this.DnsServer) + + Add-DnsServerResourceRecord @dnsParameters + } + + hidden [void] ModifyResourceRecord([Microsoft.Management.Infrastructure.CimInstance] $existingRecord, [System.Collections.Hashtable[]] $propertiesNotInDesiredState) + { + $dnsParameters = @{ + ZoneName = $this.ZoneName + ComputerName = $this.DnsServer + } + + if ($this.isScoped) + { + $dnsParameters['ZoneScope'] = $this.ZoneScope + } + + # Copy the existing record and modify values as appropriate + $newRecord = [Microsoft.Management.Infrastructure.CimInstance]::new($existingRecord) + + foreach ($propertyToChange in $propertiesNotInDesiredState) + { + switch ($propertyToChange.Property) + { + # Key parameters will never be affected, so only include Mandatory and Optional values in the switch statement + + 'TimeToLive' + { + $newRecord.TimeToLive = [System.TimeSpan] $propertyToChange.ExpectedValue + } + + } + } + + Set-DnsServerResourceRecord @dnsParameters -OldInputObject $existingRecord -NewInputObject $newRecord -Verbose + } +} diff --git a/source/Classes/004.DnsRecordNsScoped.ps1 b/source/Classes/004.DnsRecordNsScoped.ps1 new file mode 100644 index 00000000..631d1ae7 --- /dev/null +++ b/source/Classes/004.DnsRecordNsScoped.ps1 @@ -0,0 +1,63 @@ +<# + .SYNOPSIS + The DnsRecordNsScoped DSC resource manages NS DNS records against a specific zone and zone scope on a Domain Name System (DNS) server. + + .DESCRIPTION + The DnsRecordNsScoped DSC resource manages NS DNS records against a specific zone and zone scope on a Domain Name System (DNS) server. + + .PARAMETER ZoneScope + Specifies the name of a zone scope. (Key Parameter) +#> + +[DscResource()] +class DnsRecordNsScoped : DnsRecordNs +{ + [DscProperty(Key)] + [System.String] + $ZoneScope + + [DnsRecordNsScoped] Get() + { + return ([DnsRecordBase] $this).Get() + } + + [void] Set() + { + ([DnsRecordBase] $this).Set() + } + + [System.Boolean] Test() + { + return ([DnsRecordBase] $this).Test() + } + + hidden [Microsoft.Management.Infrastructure.CimInstance] GetResourceRecord() + { + return ([DnsRecordNs] $this).GetResourceRecord() + } + + hidden [DnsRecordNsScoped] NewDscResourceObjectFromRecord([Microsoft.Management.Infrastructure.CimInstance] $record) + { + $dscResourceObject = [DnsRecordNsScoped] @{ + ZoneName = $this.ZoneName + ZoneScope = $this.ZoneScope + DomainName = $this.DomainName + NameServer = $this.NameServer + TimeToLive = $record.TimeToLive.ToString() + DnsServer = $this.DnsServer + Ensure = 'Present' + } + + return $dscResourceObject + } + + hidden [void] AddResourceRecord() + { + ([DnsRecordNs] $this).AddResourceRecord() + } + + hidden [void] ModifyResourceRecord([Microsoft.Management.Infrastructure.CimInstance] $existingRecord, [System.Collections.Hashtable[]] $propertiesNotInDesiredState) + { + ([DnsRecordNs] $this).ModifyResourceRecord($existingRecord, $propertiesNotInDesiredState) + } +} diff --git a/source/Examples/Resources/DnsRecordNs/1-DnsRecordNs_Mandatory_config.ps1 b/source/Examples/Resources/DnsRecordNs/1-DnsRecordNs_Mandatory_config.ps1 new file mode 100644 index 00000000..622883e6 --- /dev/null +++ b/source/Examples/Resources/DnsRecordNs/1-DnsRecordNs_Mandatory_config.ps1 @@ -0,0 +1,56 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID 308f2896-a19f-42bf-a371-140418850175 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/DnsServerDsc/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/DnsServerDsc + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module DnsServerDsc + + +<# + .DESCRIPTION + This configuration will ensure a DNS NS record exists when only the mandatory properties are specified. +#> + +Configuration DnsRecordNs_Mandatory_config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + Node localhost + { + DnsRecordNs 'TestRecord' + { + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = 'Present' + } + } +} diff --git a/source/Examples/Resources/DnsRecordNs/2-DnsRecordNs_Full_config.ps1 b/source/Examples/Resources/DnsRecordNs/2-DnsRecordNs_Full_config.ps1 new file mode 100644 index 00000000..507852df --- /dev/null +++ b/source/Examples/Resources/DnsRecordNs/2-DnsRecordNs_Full_config.ps1 @@ -0,0 +1,58 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID 8479b7e8-d244-4eda-9725-c5d8a9ca0b97 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/DnsServerDsc/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/DnsServerDsc + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module DnsServerDsc + + +<# + .DESCRIPTION + This configuration will ensure a DNS NS record exists when all properties are specified. +#> + +Configuration DnsRecordNs_Full_config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + Node localhost + { + DnsRecordNs 'TestRecord' + { + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + TimeToLive = '01:00:00' + DnsServer = 'localhost' + Ensure = 'Present' + } + } +} diff --git a/source/Examples/Resources/DnsRecordNs/3-DnsRecordNs_Remove_config.ps1 b/source/Examples/Resources/DnsRecordNs/3-DnsRecordNs_Remove_config.ps1 new file mode 100644 index 00000000..b538c543 --- /dev/null +++ b/source/Examples/Resources/DnsRecordNs/3-DnsRecordNs_Remove_config.ps1 @@ -0,0 +1,58 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID 4f3e8876-fcae-4e1f-a879-fbde1b1fe56c + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/DnsServerDsc/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/DnsServerDsc + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module DnsServerDsc + + +<# + .DESCRIPTION + This configuration will ensure a DNS NS record does not exist when mandatory properties are specified. + + Note that not all mandatory properties are necessarily key properties. Non-key property values will be ignored when determining whether the record is to be removed. +#> + +Configuration DnsRecordNs_Remove_config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + Node localhost + { + DnsRecordNs 'TestRecord' + { + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = 'Absent' + } + } +} diff --git a/source/Examples/Resources/DnsRecordNsScoped/1-DnsRecordNsScoped_Mandatory_config.ps1 b/source/Examples/Resources/DnsRecordNsScoped/1-DnsRecordNsScoped_Mandatory_config.ps1 new file mode 100644 index 00000000..3211f969 --- /dev/null +++ b/source/Examples/Resources/DnsRecordNsScoped/1-DnsRecordNsScoped_Mandatory_config.ps1 @@ -0,0 +1,57 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID deff6e75-397f-46c8-b52c-9f60c6418783 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/DnsServerDsc/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/DnsServerDsc + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module DnsServerDsc + + +<# + .DESCRIPTION + This configuration will ensure a DNS NS record exists when only the mandatory properties are specified. +#> + +Configuration DnsRecordNsScoped_Mandatory_config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + Node localhost + { + DnsRecordNsScoped 'TestRecord' + { + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = 'Present' + } + } +} diff --git a/source/Examples/Resources/DnsRecordNsScoped/2-DnsRecordNsScoped_Full_config.ps1 b/source/Examples/Resources/DnsRecordNsScoped/2-DnsRecordNsScoped_Full_config.ps1 new file mode 100644 index 00000000..d3ffe53a --- /dev/null +++ b/source/Examples/Resources/DnsRecordNsScoped/2-DnsRecordNsScoped_Full_config.ps1 @@ -0,0 +1,59 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID b564652c-9a98-4e18-9ce9-913e21d30a5a + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/DnsServerDsc/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/DnsServerDsc + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module DnsServerDsc + + +<# + .DESCRIPTION + This configuration will ensure a DNS NS record exists when all properties are specified. +#> + +Configuration DnsRecordNsScoped_Full_config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + Node localhost + { + DnsRecordNsScoped 'TestRecord' + { + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + TimeToLive = '01:00:00' + DnsServer = 'localhost' + Ensure = 'Present' + } + } +} diff --git a/source/Examples/Resources/DnsRecordNsScoped/3-DnsRecordNsScoped_Remove_config.ps1 b/source/Examples/Resources/DnsRecordNsScoped/3-DnsRecordNsScoped_Remove_config.ps1 new file mode 100644 index 00000000..6e7b8c45 --- /dev/null +++ b/source/Examples/Resources/DnsRecordNsScoped/3-DnsRecordNsScoped_Remove_config.ps1 @@ -0,0 +1,59 @@ +<#PSScriptInfo + +.VERSION 1.0.1 + +.GUID 3088e993-8937-4103-a6a8-779760316177 + +.AUTHOR DSC Community + +.COMPANYNAME DSC Community + +.COPYRIGHT DSC Community contributors. All rights reserved. + +.TAGS DSCConfiguration + +.LICENSEURI https://github.com/dsccommunity/DnsServerDsc/blob/main/LICENSE + +.PROJECTURI https://github.com/dsccommunity/DnsServerDsc + +.ICONURI https://dsccommunity.org/images/DSC_Logo_300p.png + +.EXTERNALMODULEDEPENDENCIES + +.REQUIREDSCRIPTS + +.EXTERNALSCRIPTDEPENDENCIES + +.RELEASENOTES +Updated author, copyright notice, and URLs. + +.PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core + +#> + +#Requires -Module DnsServerDsc + + +<# + .DESCRIPTION + This configuration will ensure a DNS NS record does not exist when mandatory properties are specified. + + Note that not all mandatory properties are necessarily key properties. Non-key property values will be ignored when determining whether the record is to be removed. +#> + +Configuration DnsRecordNsScoped_Remove_config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + Node localhost + { + DnsRecordNsScoped 'TestRecord' + { + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = 'Absent' + } + } +} diff --git a/source/Private/Get-LocalizedDataRecursive.ps1 b/source/Private/Get-LocalizedDataRecursive.ps1 index fc717d57..6f05a055 100644 --- a/source/Private/Get-LocalizedDataRecursive.ps1 +++ b/source/Private/Get-LocalizedDataRecursive.ps1 @@ -14,7 +14,7 @@ classes. .PARAMETER ClassName - An array of class names, normally provided by `Get-ClassName -Recurse`. + An array of class names, normally provided by `Get-ClassName -Recurse`. .OUTPUTS Returns a string array with at least one item. diff --git a/source/en-US/DnsRecordNs.strings.psd1 b/source/en-US/DnsRecordNs.strings.psd1 new file mode 100644 index 00000000..2977996f --- /dev/null +++ b/source/en-US/DnsRecordNs.strings.psd1 @@ -0,0 +1,11 @@ +<# + .SYNOPSIS + The localized resource strings in English (en-US) for the + resource DnsRecordNs. +#> + +ConvertFrom-StringData @' + GettingDnsRecordMessage = Getting specified DNS {0} record in zone '{1}' from '{3}'. + CreatingDnsRecordMessage = Creating {0} record specified in zone '{1}' on '{3}'. + DomainZoneMismatch = Domain '{0}' must be the same as the zone specified ('{1}') or a subdomain thereof. +'@ diff --git a/source/en-US/DnsRecordNsScoped.strings.psd1 b/source/en-US/DnsRecordNsScoped.strings.psd1 new file mode 100644 index 00000000..28d8abac --- /dev/null +++ b/source/en-US/DnsRecordNsScoped.strings.psd1 @@ -0,0 +1,10 @@ +<# + .SYNOPSIS + The localized resource strings in English (en-US) for the + resource DnsRecordNsScoped. +#> + +ConvertFrom-StringData @' + GettingDnsRecordMessage = Getting specified DNS {0} record in zone '{1}' with the '{2}' scope, from '{3}'. + CreatingDnsRecordMessage = Creating {0} record specified in zone '{1}' with the '{2}' scope on '{3}'. +'@ diff --git a/tests/Integration/Classes/DnsRecordNs.config.ps1 b/tests/Integration/Classes/DnsRecordNs.config.ps1 new file mode 100644 index 00000000..c70a1be8 --- /dev/null +++ b/tests/Integration/Classes/DnsRecordNs.config.ps1 @@ -0,0 +1,105 @@ +$zoneName = "Ns.test" + +$ConfigurationData = @{ + AllNodes = , @{ + NodeName = 'localhost' + CertificateFile = $Null + } + NonNodeData = @{ + DnsRecordNs_CreateRecord_Config = @{ + ZoneName = $zoneName + DomainName = $zoneName + NameServer = 'ns.contoso.com' + } + DnsRecordNs_ModifyRecord_Config = @{ + ZoneName = $zoneName + DomainName = $zoneName + NameServer = 'ns.contoso.com' + DnsServer = 'localhost' + TimeToLive = '05:00:00' + Ensure = 'Present' + } + DnsRecordNs_DeleteRecord_Config = @{ + ZoneName = $zoneName + DomainName = $zoneName + NameServer = 'ns.contoso.com' + Ensure = 'Absent' + } + } +} + +<# + .SYNOPSIS + Create an NS record +#> +configuration DnsRecordNs_CreateRecord_Config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + node $AllNodes.NodeName + { + DnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsRecordNs 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordNs_CreateRecord_Config.ZoneName + DomainName = $ConfigurationData.NonNodeData.DnsRecordNs_CreateRecord_Config.DomainName + NameServer = $ConfigurationData.NonNodeData.DnsRecordNs_CreateRecord_Config.NameServer + } + } +} + +<# + .SYNOPSIS + Modifies an existing NS record +#> +configuration DnsRecordNs_ModifyRecord_Config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + node $AllNodes.NodeName + { + DnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsRecordNs 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordNs_ModifyRecord_Config.ZoneName + DomainName = $ConfigurationData.NonNodeData.DnsRecordNs_ModifyRecord_Config.DomainName + NameServer = $ConfigurationData.NonNodeData.DnsRecordNs_ModifyRecord_Config.NameServer + DnsServer = $ConfigurationData.NonNodeData.DnsRecordNs_ModifyRecord_Config.DnsServer + TimeToLive = $ConfigurationData.NonNodeData.DnsRecordNs_ModifyRecord_Config.TimeToLive + Ensure = $ConfigurationData.NonNodeData.DnsRecordNs_ModifyRecord_Config.Ensure + } + } +} + +<# + .SYNOPSIS + Deletes an existing NS record +#> +configuration DnsRecordNs_DeleteRecord_Config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + node $AllNodes.NodeName + { + DnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsRecordNs 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordNs_DeleteRecord_Config.ZoneName + DomainName = $ConfigurationData.NonNodeData.DnsRecordNs_DeleteRecord_Config.DomainName + NameServer = $ConfigurationData.NonNodeData.DnsRecordNs_DeleteRecord_Config.NameServer + Ensure = $ConfigurationData.NonNodeData.DnsRecordNs_DeleteRecord_Config.Ensure + } + } +} diff --git a/tests/Integration/Classes/DnsRecordNs.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordNs.integration.tests.ps1 new file mode 100644 index 00000000..00337414 --- /dev/null +++ b/tests/Integration/Classes/DnsRecordNs.integration.tests.ps1 @@ -0,0 +1,220 @@ +$script:dscModuleName = 'DnsServerDsc' +$script:dscResourceFriendlyName = 'DnsRecordNs' +$script:dscResourceName = "$($script:dscResourceFriendlyName)" + +try +{ + Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' +} +catch [System.IO.FileNotFoundException] +{ + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' +} + +$initializationParams = @{ + DSCModuleName = $script:dscModuleName + DSCResourceName = $script:dscResourceName + ResourceType = 'Class' + TestType = 'Integration' +} +$script:testEnvironment = Initialize-TestEnvironment @initializationParams + +# Using try/finally to always cleanup. +try +{ + #region Integration Tests + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null + + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + Wait-ForIdleLcm -Clear + + $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + Wait-ForIdleLcm -Clear + + $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + } + + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' + + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + } + #endregion +} +finally +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} diff --git a/tests/Integration/Classes/DnsRecordNsScoped.config.ps1 b/tests/Integration/Classes/DnsRecordNsScoped.config.ps1 new file mode 100644 index 00000000..a5b515c6 --- /dev/null +++ b/tests/Integration/Classes/DnsRecordNsScoped.config.ps1 @@ -0,0 +1,127 @@ +$zoneName = "Ns.test" +$zoneScope = 'external' + +$ConfigurationData = @{ + AllNodes = , @{ + NodeName = 'localhost' + CertificateFile = $Null + } + NonNodeData = @{ + DnsRecordNsScoped_CreateRecord_Config = @{ + ZoneName = $zoneName + ZoneScope = $zoneScope + DomainName = $zoneName + NameServer = 'ns.contoso.com' + } + DnsRecordNsScoped_ModifyRecord_Config = @{ + ZoneName = $zoneName + ZoneScope = $zoneScope + DomainName = $zoneName + NameServer = 'ns.contoso.com' + DnsServer = 'localhost' + TimeToLive = '05:00:00' + Ensure = 'Present' + } + DnsRecordNsScoped_DeleteRecord_Config = @{ + ZoneName = $zoneName + ZoneScope = $zoneScope + DomainName = $zoneName + NameServer = 'ns.contoso.com' + Ensure = 'Absent' + } + } +} + +<# + .SYNOPSIS + Create an NS record +#> +configuration DnsRecordNsScoped_CreateRecord_Config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + node $AllNodes.NodeName + { + DnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsServerZoneScope "external scope" { + ZoneName = $zoneName + Name = $zoneScope + } + + DnsRecordNsScoped 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordNsScoped_CreateRecord_Config.ZoneName + ZoneScope = $ConfigurationData.NonNodeData.DnsRecordNsScoped_CreateRecord_Config.ZoneScope + DomainName = $ConfigurationData.NonNodeData.DnsRecordNsScoped_CreateRecord_Config.DomainName + NameServer = $ConfigurationData.NonNodeData.DnsRecordNsScoped_CreateRecord_Config.NameServer + } + } +} + +<# + .SYNOPSIS + Modifies an existing NS record +#> +configuration DnsRecordNsScoped_ModifyRecord_Config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + node $AllNodes.NodeName + { + DnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsServerZoneScope "external scope" { + ZoneName = $zoneName + Name = $zoneScope + } + + DnsRecordNsScoped 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordNsScoped_ModifyRecord_Config.ZoneName + ZoneScope = $ConfigurationData.NonNodeData.DnsRecordNsScoped_ModifyRecord_Config.ZoneScope + DomainName = $ConfigurationData.NonNodeData.DnsRecordNsScoped_ModifyRecord_Config.DomainName + NameServer = $ConfigurationData.NonNodeData.DnsRecordNsScoped_ModifyRecord_Config.NameServer + DnsServer = $ConfigurationData.NonNodeData.DnsRecordNsScoped_ModifyRecord_Config.DnsServer + TimeToLive = $ConfigurationData.NonNodeData.DnsRecordNsScoped_ModifyRecord_Config.TimeToLive + Ensure = $ConfigurationData.NonNodeData.DnsRecordNsScoped_ModifyRecord_Config.Ensure + } + } +} + +<# + .SYNOPSIS + Deletes an existing NS record +#> +configuration DnsRecordNsScoped_DeleteRecord_Config +{ + Import-DscResource -ModuleName 'DnsServerDsc' + + node $AllNodes.NodeName + { + DnsServerPrimaryZone "Zone $zoneName" + { + Name = $zoneName + } + + DnsServerZoneScope "external scope" { + ZoneName = $zoneName + Name = $zoneScope + } + + DnsRecordNsScoped 'Integration_Test' + { + ZoneName = $ConfigurationData.NonNodeData.DnsRecordNsScoped_DeleteRecord_Config.ZoneName + ZoneScope = $ConfigurationData.NonNodeData.DnsRecordNsScoped_DeleteRecord_Config.ZoneScope + DomainName = $ConfigurationData.NonNodeData.DnsRecordNsScoped_DeleteRecord_Config.DomainName + NameServer = $ConfigurationData.NonNodeData.DnsRecordNsScoped_DeleteRecord_Config.NameServer + Ensure = $ConfigurationData.NonNodeData.DnsRecordNsScoped_DeleteRecord_Config.Ensure + } + } +} diff --git a/tests/Integration/Classes/DnsRecordNsScoped.integration.tests.ps1 b/tests/Integration/Classes/DnsRecordNsScoped.integration.tests.ps1 new file mode 100644 index 00000000..8eb5b13d --- /dev/null +++ b/tests/Integration/Classes/DnsRecordNsScoped.integration.tests.ps1 @@ -0,0 +1,220 @@ +$script:dscModuleName = 'DnsServerDsc' +$script:dscResourceFriendlyName = 'DnsRecordNsScoped' +$script:dscResourceName = "$($script:dscResourceFriendlyName)" + +try +{ + Import-Module -Name DscResource.Test -Force -ErrorAction 'Stop' +} +catch [System.IO.FileNotFoundException] +{ + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -Tasks build" first.' +} + +$initializationParams = @{ + DSCModuleName = $script:dscModuleName + DSCResourceName = $script:dscResourceName + ResourceType = 'Class' + TestType = 'Integration' +} +$script:testEnvironment = Initialize-TestEnvironment @initializationParams + +# Using try/finally to always cleanup. +try +{ + #region Integration Tests + $configurationFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:dscResourceName).config.ps1" + . $configurationFile + + Describe "$($script:dscResourceName)_Integration" { + BeforeAll { + $resourceId = "[$($script:dscResourceFriendlyName)]Integration_Test" + } + + $configurationName = "$($script:dscResourceName)_CreateRecord_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + + # Optional properties were not specified, so we just need to ensure the value exists + $resourceCurrentState.TimeToLive | Should -Not -Be $null + + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be 'localhost' + $resourceCurrentState.Ensure | Should -Be 'Present' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + Wait-ForIdleLcm -Clear + + $configurationName = "$($script:dscResourceName)_ModifyRecord_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + + # Optional properties + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + + # Defaulted properties + $resourceCurrentState.DnsServer | Should -Be $shouldBeData.DnsServer + $resourceCurrentState.Ensure | Should -Be $shouldBeData.Ensure + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + Wait-ForIdleLcm -Clear + + $configurationName = "$($script:dscResourceName)_DeleteRecord_Config" + + Context ('When using configuration {0}' -f $configurationName) { + It 'Should compile and apply the MOF without throwing' { + { + $configurationParameters = @{ + OutputPath = $TestDrive + ConfigurationData = $ConfigurationData + } + + & $configurationName @configurationParameters + + $startDscConfigurationParameters = @{ + Path = $TestDrive + ComputerName = 'localhost' + Wait = $true + Verbose = $true + Force = $true + ErrorAction = 'Stop' + } + + Start-DscConfiguration @startDscConfigurationParameters + } | Should -Not -Throw + } + + It 'Should be able to call Get-DscConfiguration without throwing' { + { + $script:currentConfiguration = Get-DscConfiguration -Verbose -ErrorAction Stop + } | Should -Not -Throw + } + + It 'Should have set the resource and all the parameters should match' { + $resourceCurrentState = $script:currentConfiguration | Where-Object -FilterScript { + $_.ConfigurationName -eq $configurationName -and $_.ResourceId -eq $resourceId + } + + $shouldBeData = $ConfigurationData.NonNodeData.$configurationName + + # Key properties + $resourceCurrentState.ZoneName | Should -Be $shouldBeData.ZoneName + $resourceCurrentState.ZoneScope | Should -Be $shouldBeData.ZoneScope + $resourceCurrentState.DomainName | Should -Be $shouldBeData.DomainName + $resourceCurrentState.NameServer | Should -Be $shouldBeData.NameServer + + # Optional properties + if ($shouldBeData.TimeToLive) + { + $resourceCurrentState.TimeToLive | Should -Be $shouldBeData.TimeToLive + } + + # DnsServer is not specified in this test, so it defaults to 'localhost' + $resourceCurrentState.DnsServer | Should -Be 'localhost' + + # Ensure will be Absent + $resourceCurrentState.Ensure | Should -Be 'Absent' + } + + It 'Should return $true when Test-DscConfiguration is run' { + Test-DscConfiguration -Verbose | Should -Be 'True' + } + } + + } + #endregion +} +finally +{ + Restore-TestEnvironment -TestEnvironment $script:testEnvironment +} diff --git a/tests/Unit/Classes/DnsRecordNs.tests.ps1 b/tests/Unit/Classes/DnsRecordNs.tests.ps1 new file mode 100644 index 00000000..18a85184 --- /dev/null +++ b/tests/Unit/Classes/DnsRecordNs.tests.ps1 @@ -0,0 +1,357 @@ +<# + This pester file is an example of how organize a pester test. + There tests are based to dummy scenario. + Replace all properties, and mock commands by yours. +#> + +$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path +$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { + ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and + $(try + { + Test-ModuleManifest $_.FullName -ErrorAction Stop + } + catch + { + $false + }) } +).BaseName + +Import-Module $ProjectName + +Get-Module -Name 'DnsServer' -All | Remove-Module -Force +Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + +InModuleScope $ProjectName { + Describe DnsRecordNs -Tag 'DnsRecord', 'DnsRecordNs' { + Context 'Constructors' { + It 'Should not throw an exception when instantiated' { + { [DnsRecordNs]::new() } | Should -Not -Throw + } + + It 'Has a default or empty constructor' { + $instance = [DnsRecordNs]::new() + $instance | Should -Not -BeNullOrEmpty + } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordNs' { + $instance = [DnsRecordNs]::new() + $instance.GetType().Name | Should -Be 'DnsRecordNs' + } + } + } + + Describe "Testing DnsRecordNs Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordNs' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + } + } + + Context "When the configuration is absent" { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + } + } + + It 'Should return the state as absent' { + $currentState = $script:instanceDesiredState.Get() + + Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + $currentState.Ensure | Should -Be 'Absent' + } + + It 'Should return the same values as present in Key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName + $getMethodResourceResult.DomainName | Should -Be $script:instanceDesiredState.DomainName + $getMethodResourceResult.NameServer | Should -Be $script:instanceDesiredState.NameServer + } + + It 'Should return $false or $null respectively for the rest of the non-key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + + $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty + $getMethodResourceResult.DnsServer | Should -Be 'localhost' + } + } + + Context "When the configuration is present" { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" + } + } + + It 'Should return the state as present' { + $currentState = $script:instanceDesiredState.Get() + + Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + $currentState.Ensure | Should -Be 'Present' + } + + It 'Should return the same values as present in Key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + $getMethodResourceResult.DomainName | Should -Be $script:instanceDesiredState.DomainName + $getMethodResourceResult.NameServer | Should -Be $script:instanceDesiredState.NameServer + } + } + + It "Should throw when the zone name and domain name do not match" { + $script:instanceDesiredState.DomainName = "adventureworks.com" + { $script:instanceDesiredState.getRecordName() } | Should -Throw + } + } + + Describe "Testing DnsRecordNs Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordNs' { + BeforeAll { + } + + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + } + + It 'Should return $true' { + $script:instanceDesiredState.Test() | Should -BeTrue + } + } + + Context 'When the configuration are present' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + } + + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + } + + It 'Should return $true' { + $script:instanceDesiredState.Test() | Should -BeTrue + } + } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + } + It 'Should return $false' { + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + + Context 'When the configuration should be present' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + TimeToLive = '1:00:00' + Ensure = [Ensure]::Present + } + } + + It 'Should return $false when the object is not found' { + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + + $testCasesToFail = @( + @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + param + ( + [System.String] $ZoneName, + [System.String] $DomainName, + [System.String] $NameServer, + [System.String] $TimeToLive + ) + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNs] @{ + ZoneName = $ZoneName + DomainName = $DomainName + NameServer = $NameServer + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + } + } + + Describe "Testing DnsRecordNs Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordNs' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose + } -Verifiable + } + + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" + + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + + return $mockRecord + } + } + + Context 'When the configuration should be absent' { + BeforeAll { + $script:instanceDesiredState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + } + + BeforeEach { + $script:instanceDesiredState.Ensure = [Ensure]::Absent + } + + It 'Should call the correct mocks' { + { $script:instanceDesiredState.Set() } | Should -Not -Throw + Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + } + + Context 'When the configuration should be present' { + BeforeAll { + $script:instanceDesiredState = [DnsRecordNs] @{ + ZoneName = 'contoso.com' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + TimeToLive = '1:00:00' + Ensure = [Ensure]::Present + } + } + + BeforeEach { + $script:instanceDesiredState.Ensure = 'Present' + } + + It 'Should call the correct mocks when record exists' { + { $script:instanceDesiredState.Set() } | Should -Not -Throw + + Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + return + } + + { $script:instanceDesiredState.Set() } | Should -Not -Throw + + Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + } + + Assert-VerifiableMock + } + } +} diff --git a/tests/Unit/Classes/DnsRecordNsScoped.tests.ps1 b/tests/Unit/Classes/DnsRecordNsScoped.tests.ps1 new file mode 100644 index 00000000..365e7749 --- /dev/null +++ b/tests/Unit/Classes/DnsRecordNsScoped.tests.ps1 @@ -0,0 +1,370 @@ +<# + This pester file is an example of how organize a pester test. + There tests are based to dummy scenario. + Replace all properties, and mock commands by yours. +#> + +$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path +$ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object -FilterScript { + ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and + $(try + { + Test-ModuleManifest $_.FullName -ErrorAction Stop + } + catch + { + $false + }) } +).BaseName + +Import-Module $ProjectName + +Get-Module -Name 'DnsServer' -All | Remove-Module -Force +Import-Module -Name "$($PSScriptRoot)\..\Stubs\DnsServer.psm1" + +InModuleScope $ProjectName { + + Describe DnsRecordNsScoped -Tag 'DnsRecord', 'DnsRecordNsScoped' { + + Context 'Constructors' { + It 'Should not throw an exception when instantiate' { + { [DnsRecordNsScoped]::new() } | Should -Not -Throw + } + + It 'Has a default or empty constructor' { + $instance = [DnsRecordNsScoped]::new() + $instance | Should -Not -BeNullOrEmpty + } + } + + Context 'Type creation' { + It 'Should be type named DnsRecordNsScoped' { + $instance = [DnsRecordNsScoped]::new() + $instance.GetType().Name | Should -Be 'DnsRecordNsScoped' + } + } + } + + Describe "Testing DnsRecordNsScoped Get Method" -Tag 'Get', 'DnsRecord', 'DnsRecordNsScoped' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + } + } + + Context "When the configuration is absent" { + BeforeAll { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + } + } + + It 'Should return the state as absent' { + $currentState = $script:instanceDesiredState.Get() + + Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + $currentState.Ensure | Should -Be 'Absent' + } + + It 'Should return the same values as present in Key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + $getMethodResourceResult.ZoneName | Should -Be $script:instanceDesiredState.ZoneName + $getMethodResourceResult.ZoneScope | Should -Be $script:instanceDesiredState.ZoneScope + $getMethodResourceResult.DomainName | Should -Be $script:instanceDesiredState.DomainName + $getMethodResourceResult.NameServer | Should -Be $script:instanceDesiredState.NameServer + } + + It 'Should return $false or $null respectively for the rest of the non-key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + + $getMethodResourceResult.TimeToLive | Should -BeNullOrEmpty + $getMethodResourceResult.DnsServer | Should -Be 'localhost' + } + } + + Context "When the configuration is present" { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + return Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" + } + } + + It 'Should return the state as present' { + $currentState = $script:instanceDesiredState.Get() + + Assert-MockCalled Get-DnsServerResourceRecord -Exactly -Times 1 -Scope It + $currentState.Ensure | Should -Be 'Present' + } + + It 'Should return the same values as present in Key properties' { + $getMethodResourceResult = $script:instanceDesiredState.Get() + + $getMethodResourceResult.DomainName | Should -Be $script:instanceDesiredState.DomainName + $getMethodResourceResult.NameServer | Should -Be $script:instanceDesiredState.NameServer + } + } + + } + + Describe "Testing DnsRecordNsScoped Test Method" -Tag 'Test', 'DnsRecord', 'DnsRecordNsScoped' { + BeforeAll { + } + + Context 'When the system is in the desired state' { + Context 'When the configuration are absent' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + } + + It 'Should return $true' { + $script:instanceDesiredState.Test() | Should -BeTrue + } + } + + Context 'When the configuration are present' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + } + + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + } + + It 'Should return $true' { + $script:instanceDesiredState.Test() | Should -BeTrue + } + } + } + + Context 'When the system is not in the desired state' { + Context 'When the configuration should be absent' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + } + It 'Should return $false' { + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + + Context 'When the configuration should be present' { + BeforeEach { + $script:instanceDesiredState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + TimeToLive = '1:00:00' + Ensure = [Ensure]::Present + } + } + + It 'Should return $false when the object is not found' { + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + + return $mockInstanceCurrentState + } + $script:instanceDesiredState.Test() | Should -BeFalse + } + + $testCasesToFail = @( + @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + DnsServer = 'localhost' + TimeToLive = '02:00:00' # Undesired + Ensure = 'Present' + } + ) + + It 'Should return $false when non-key values are not in the desired state.' -TestCases $testCasesToFail { + param + ( + [System.String] $ZoneName, + [System.String] $ZoneScope, + [System.String] $DomainName, + [System.String] $NameServer, + [System.String] $TimeToLive + ) + #Override Get() method + $script:instanceDesiredState | Add-Member -Force -MemberType ScriptMethod -Name Get -Value { + $mockInstanceCurrentState = [DnsRecordNsScoped] @{ + ZoneName = $ZoneName + ZoneScope = $ZoneScope + DomainName = $DomainName + NameServer = $NameServer + Ensure = [Ensure]::Present + } + + return $mockInstanceCurrentState + } + + $script:instanceDesiredState.Test() | Should -BeFalse + } + } + } + } + + Describe "Testing DnsRecordNsScoped Set Method" -Tag 'Set', 'DnsRecord', 'DnsRecordNsScoped' { + BeforeAll { + # Mock the Add-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Add-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Add-DnsServerResourceRecord Called" -Verbose + } -Verifiable + + # Mock the Remove-DnsServerResourceRecord cmdlet to return nothing + Mock -CommandName Remove-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Remove-DnsServerResourceRecord Called" -Verbose + } -Verifiable + + Mock -CommandName Set-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Set-DnsServerResourceRecord Called" -Verbose + } -Verifiable + } + + Context 'When the system is not in the desired state' { + BeforeAll { + $mockInstancesPath = Resolve-Path -Path $PSScriptRoot + + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + $mockRecord = Import-Clixml -Path "$($mockInstancesPath)\..\MockObjects\NsRecordInstance.xml" + + # Set a wrong value + $mockRecord.TimeToLive = [System.TimeSpan] '2:00:00' + + return $mockRecord + } + } + + Context 'When the configuration should be absent' { + BeforeAll { + $script:instanceDesiredState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + Ensure = [Ensure]::Absent + } + } + + BeforeEach { + $script:instanceDesiredState.Ensure = [Ensure]::Absent + } + + It 'Should call the correct mocks' { + { $script:instanceDesiredState.Set() } | Should -Not -Throw + Assert-MockCalled -CommandName Get-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + Assert-MockCalled -CommandName Remove-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + } + + Context 'When the configuration should be present' { + BeforeAll { + $script:instanceDesiredState = [DnsRecordNsScoped] @{ + ZoneName = 'contoso.com' + ZoneScope = 'external' + DomainName = 'contoso.com' + NameServer = 'ns.contoso.com' + TimeToLive = '1:00:00' + Ensure = [Ensure]::Present + } + } + + BeforeEach { + $script:instanceDesiredState.Ensure = 'Present' + } + + It 'Should call the correct mocks when record exists' { + { $script:instanceDesiredState.Set() } | Should -Not -Throw + + Assert-MockCalled -CommandName Set-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + + It 'Should call the correct mocks when record does not exist' { + Mock -CommandName Get-DnsServerResourceRecord -MockWith { + Write-Verbose "Mock Get-DnsServerResourceRecord Called" -Verbose + + return + } + + { $script:instanceDesiredState.Set() } | Should -Not -Throw + + Assert-MockCalled -CommandName Add-DnsServerResourceRecord -Exactly -Times 1 -Scope 'It' + } + } + + Assert-VerifiableMock + } + } +} diff --git a/tests/Unit/MockObjects/NsRecordInstance.xml b/tests/Unit/MockObjects/NsRecordInstance.xml new file mode 100644 index 00000000..72f88ee1 --- /dev/null +++ b/tests/Unit/MockObjects/NsRecordInstance.xml @@ -0,0 +1,91 @@ + + + + Microsoft.Management.Infrastructure.CimInstance#root/Microsoft/Windows/DNS/DnsServerResourceRecord + Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Windows/DNS/DnsDomain + Microsoft.Management.Infrastructure.CimInstance#DnsServerResourceRecord + Microsoft.Management.Infrastructure.CimInstance#DnsDomain + Microsoft.Management.Infrastructure.CimInstance + System.Object + + DnsServerResourceRecord + + @ + @ + IN + + + Microsoft.Management.Infrastructure.CimInstance#root/Microsoft/Windows/DNS/DnsServerResourceRecordNS + Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Windows/DNS/DnsServerResourceRecordData + Microsoft.Management.Infrastructure.CimInstance#DnsServerResourceRecordNS + Microsoft.Management.Infrastructure.CimInstance#DnsServerResourceRecordData + Microsoft.Management.Infrastructure.CimInstance + System.Object + + DnsServerResourceRecordNS + + ns.contoso.com. + + + + + + System.Collections.ArrayList + System.Object + + + + + DnsServerResourceRecordData + ROOT/Microsoft/Windows/DNS + dnstest + -315208600 + <CLASS NAME="DnsServerResourceRecordData"><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER></CLASS> + + + + + DnsServerResourceRecordNS + root/Microsoft/Windows/DNS + dnstest + -315190920 + <CLASS NAME="DnsServerResourceRecordNS" SUPERCLASS="DnsServerResourceRecordData"><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><PROPERTY NAME="NameServer" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="write" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY></CLASS> + + + + + + + NS + + PT1H + 2 + + + + + + + + + DnsDomain + ROOT/Microsoft/Windows/DNS + dnstest + -315198200 + <CLASS NAME="DnsDomain"><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER><PROPERTY NAME="DistinguishedName" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY></CLASS> + + + + + DnsServerResourceRecord + root/Microsoft/Windows/DNS + dnstest + -315204440 + <CLASS NAME="DnsServerResourceRecord" SUPERCLASS="DnsDomain"><QUALIFIER NAME="dynamic" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="provider" TYPE="string"><VALUE>DnsServerPSProvider</VALUE></QUALIFIER><QUALIFIER NAME="ClassVersion" TYPE="string"><VALUE>1.0.0</VALUE></QUALIFIER><QUALIFIER NAME="locale" TYPE="sint32" TOSUBCLASS="false"><VALUE>1033</VALUE></QUALIFIER><PROPERTY NAME="HostName" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="RecordClass" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="ValueMap" TYPE="string"><VALUE.ARRAY><VALUE>IN</VALUE><VALUE>CSNET</VALUE><VALUE>CHAOS</VALUE><VALUE>Hesiod</VALUE></VALUE.ARRAY></QUALIFIER></PROPERTY><PROPERTY NAME="RecordData" TYPE="string"><QUALIFIER NAME="EmbeddedInstance" TYPE="string"><VALUE>DnsServerResourceRecordData</VALUE></QUALIFIER><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="write" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="RecordType" TYPE="string"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="ValueMap" TYPE="string"><VALUE.ARRAY><VALUE>A</VALUE><VALUE>Ns</VALUE><VALUE>Md</VALUE><VALUE>Mf</VALUE><VALUE>CName</VALUE><VALUE>Soa</VALUE><VALUE>Mb</VALUE><VALUE>Mg</VALUE><VALUE>Mr</VALUE><VALUE>Null</VALUE><VALUE>Wks</VALUE><VALUE>Ptr</VALUE><VALUE>HInfo</VALUE><VALUE>MInfo</VALUE><VALUE>Mx</VALUE><VALUE>Text</VALUE><VALUE>Rp</VALUE><VALUE>Afsdb</VALUE><VALUE>X25</VALUE><VALUE>Isdn</VALUE><VALUE>Rt</VALUE><VALUE>Nsap</VALUE><VALUE>NsapPtr</VALUE><VALUE>Sig</VALUE><VALUE>Key</VALUE><VALUE>Px</VALUE><VALUE>Gpos</VALUE><VALUE>AAAA</VALUE><VALUE>Loc</VALUE><VALUE>Nxt</VALUE><VALUE>Eid</VALUE><VALUE>NimLoc</VALUE><VALUE>Srv</VALUE><VALUE>Atma</VALUE><VALUE>Naptr</VALUE><VALUE>Kx</VALUE><VALUE>Cert</VALUE><VALUE>A6</VALUE><VALUE>DName</VALUE><VALUE>Sink</VALUE><VALUE>Opt</VALUE><VALUE>Ds</VALUE><VALUE>Rrsig</VALUE><VALUE>NSEC</VALUE><VALUE>DnsKey</VALUE><VALUE>DhcId</VALUE><VALUE>Wins</VALUE><VALUE>WinsR</VALUE><VALUE>TLSA</VALUE><VALUE>UNKNOWN</VALUE></VALUE.ARRAY></QUALIFIER></PROPERTY><PROPERTY NAME="Timestamp" TYPE="datetime"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="TimeToLive" TYPE="datetime"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER><QUALIFIER NAME="write" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY><PROPERTY NAME="Type" TYPE="uint16"><QUALIFIER NAME="read" TYPE="boolean"><VALUE>true</VALUE></QUALIFIER></PROPERTY></CLASS> + + + + + + +