DnsStig.psm1
Function Set-DnsServerStig { <# .SYNOPSIS Implements all STIGs contained in this module within the specified forest. .DESCRIPTION The Set-DnsServerStig cmdlet implements all of the STIGs in this module. .PARAMETER Forest The DNS Forest to configure. .PARAMETER RemoveProhibitedRecords Option to remove found prohibited records of type HINFO, RP, TXT, and LOC. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerStig Implements all STIGs contained in this module within the specified forest, but does not removed prohibited record types. .EXAMPLE PS C:\>Set-DnsServerStig -RemoveProhibitedRecords Implements all STIG settings contained in this module and removes prohibited record types. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [switch]$RemoveProhibitedRecords = $false, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Starting DNS STIG" if ($RemoveProhibitedRecords) { Remove-DnsServerProhibitedRecords -Forest $Forest -Credential $Credential } else { Get-DnsServerProhibitedRecords -Forest $Forest -Credential $Credential | ForEach-Object { Write-Warning ($_.Record | Out-String) } } Get-DnsServersRunningIPv6 -Forest $Forest -Credential $Credential | ForEach-Object { Write-Warning $_.ComputerName } Get-InactiveDnsServers -Forest $Forest | ForEach-Object { Write-Warning "Inactive server: $_" } Set-DnsServerZoneSecureUpdates -Forest $Forest -Credential $Credential Set-DnsServerDisableRootHints -Forest $Forest -Credential $Credential Set-DnsServerRecursionAndForwarders -Forest $Forest -Credential $Credential Set-DnsServerCryptoFolderPermissions -Forest $Forest -Credential $Credential Set-DnsServerZoneTransfers -Forest $Forest -Credential $Credential Set-DnsServerLogPermissions -Forest $Forest -Credential $Credential Set-DnsServerLogging -Forest $Forest -Credential $Credential Set-DnsServerVersionQuery -Forest $Forest -Credential $Credential Remove-DnsServerZoneIPv6LinkLocalAddresses -Forest $Forest -Credential $Credential } End {} } Function Remove-DnsServerProhibitedRecords { <# .SYNOPSIS The HINFO, RP, TXT and LOC RR types must not be used in the zone SOA. .DESCRIPTION The Remove-DnsServerProhibitedRecords cmdlet gets and then removes all prohibited records from each zone in the forest. .PARAMETER Forest The DNS Forest to configure. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Remove-DnsServerProhibitedRecords Removes all of the prohibited records in the current user forest. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-SI-000004 Rule ID SV-73169r1 Vuln ID V-58739 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter(Position=1)] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Removing DNS Server Prohibited Entries." Get-DnsServerProhibitedRecords -Forest $Forest -Credential $Credential | ForEach-Object { $Record = ($_.Record | Out-String) Write-Warning "Removing record $Record" try { $Server = Resolve-DnsName -Name $_.ZoneName -ErrorAction Stop | Select-Object -ExpandProperty PrimaryServer if ([System.String]::IsNullOrEmpty($Server)) { Write-Warning "PrimaryServer attribute was null, using the zone name for the server." $Server = $_.ZoneName } Remove-DnsServerResourceRecord -ZoneName $_.ZoneName -ComputerName $Server -InputObject $_.Record -Force -Confirm:$false } catch [Exception] { Write-Warning "Error removing record $Record`: $($_.ToString())" } } Write-Host "Removing prohibited entries complete." } End { } } Function Get-DnsServerProhibitedRecords { <# .SYNOPSIS The HINFO, RP, TXT and LOC RR types must not be used in the zone SOA. .DESCRIPTION The Get-DnsServerProhibitedRecords cmdlet gets all prohibited records from each zone in the forest. .PARAMETER Forest The DNS Forest to search. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Get-DnsServerProhibitedRecords Gets all of the prohibited records in the current user forest. .INPUTS System.String .OUTPUTS PSObject[] .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-SI-000004 Rule ID SV-73169r1 Vuln ID V-58739 Severity CAT II #> Param( [Parameter(Position=0, ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { Write-Host "Getting DNS Server prohibited entries." $BadRecords = @() Get-ForestDnsZones -ZoneType All -LookupType Forward -Forest $Forest -Credential $Credential | ForEach-Object { try { Write-Host "Getting entries for zone $($_.ZoneName)" $Zone = $_.ZoneName $Server = Resolve-DnsName -Name $_.ZoneName -ErrorAction Stop | Select-Object -ExpandProperty PrimaryServer if ([System.String]::IsNullOrEmpty($Server)) { Write-Warning "PrimaryServer attribute was null, using the zone name for the server." $Server = $_.ZoneName } $Records = @(Get-DnsServerResourceRecord -ComputerName $Server -ZoneName $_.ZoneName | Where-Object {$_.RecordType -in @("Hinfo","RP","TXT","LOC")}) if ($Records.Count -gt 0) { foreach ($Record in $Records) { $BadRecords += @{Record=($Record);ZoneName=$_.ZoneName} } } } catch [Exception] { Write-Warning "Error getting resource records for $Zone : $($_.ToString())" } } Write-Output -InputObject $BadRecords } End { } } Function Get-DnsServersRunningIPv6 { <# .SYNOPSIS When IPv6 protocol is installed, the server must also be configured to answer for IPv6 AAAA records. .DESCRIPTION The Get-DnsServersRunningIPv6 checks each DNS server in the forest to see if it has IPv6 enabled. If it does, but does not host AAAA records, it is returned as part of an array. .PARAMETER Forest The DNS Forest to test. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Get-DnsServersRunningIPv6 Gets all of the DNS servers in the forest running IPv6 and not hosting AAAA records. .INPUTS System.String .OUTPUTS PSObject[] .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-CM-000028 Rule ID SV-73057r1 Vuln ID V-58627 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { Write-Host "Getting DNS Servers running IPv6 and not hosting AAAA records." #0xFFFFFFFF - IPv6 Disabled On All Interfaces #0xFFFFFFFE - IPv6 Enabled only on tunnel interfaces #0xFFFFFFEF - IPv6 Disabled On Tunnel Interfaces, Enabled On All Others #0xFFFFFFEE - IPv6 Disabled On Loopback Interface, Enabled On All Others #0xFFFFFFDF - IPv6 Disabled, Prefer IPv6 over IpV4 #0xFFFFFFDE - IPv6 Enabled Only On Tunnel Interfaces, Prefer IPv6 of IPv4 #0xFFFFFFCF - IPv6 Enabled On All Non Tunnel Interfaces, Prefer IPv6 over IPv4 #0xFFFFFFCE - IPv6 Disabled On Loopback Interface, Prefer IPv6 over IPv4 #0x000000FF - IPv6 Disabled On All Interfaces #0x00000020 - IPv6 Prefer IPv4 over IPv6 by changing entries in prefix policy table = 100000 #0x00000010 - IPv6 Disabled on LAN and PPP interfaces = 010000 #0x00000008 - Disable Teredo = 001000 #0x00000004 - Disable ISATAP = 000100 #0x00000002 - Disable 6to4 = 000010 #0x00000001 - IPv6 Disabled on Tunnel Interfaces including ISATAP, 6to4 and Teredo = 000001 $DnsServers = Get-ForestDnsServers -Forest $Forest -Credential $Credential $Zones = Get-ForestDnsZones -Forest $Forest -LookupType Forward -Credential $Credential $BadZones = @() foreach ($Server in $DnsServers) { $RegPropertyExists = Invoke-Command -ComputerName $Server -ScriptBlock ${function:Test-RegistryEntry} -ArgumentList "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters","DisabledComponents" -Credential $Credential if ($RegPropertyExists) { $State = Invoke-Command -ComputerName $Server -ScriptBlock {Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" -Name DisabledComponents} -Credential $Credential $DisabledValues = @([System.Convert]::ToString(0xFFFFFFFF, 16), [System.Convert]::ToString(0xFFFFFFFE, 16), [System.Convert]::ToString(0x00000011, 16)) } #If IPv6 isn't disabled on the entire system check each individual adapter if (-not $RegPropertyExists -or (-not $DisabledValues.Contains([System.Convert]::ToString($State.DisabledComponents, 16)))) { #Will return the number of network adapters with IPv6 Binding enabled $Adapters = @(Invoke-Command -ComputerName $Server -ScriptBlock {Get-NetAdapter | Where-Object{ (Get-NetAdapterBinding -InterfaceDESCRIPTION $_.InterfaceDESCRIPTION -ErrorAction SilentlyContinue | Where-Object {$_.ComponentID -eq "ms_tcpip6" -and $_.Enabled -eq $true})}} -Credential $Credential) if ($Adapters.Count -gt 0) { Get-SpecificServerDnsZones -ComputerName $Server -LookupType Forward | ForEach-Object { if (@(Get-DnsServerResourceRecord -ComputerName $Server -RRType AAAA -ZoneName $_.ZoneName).Count -eq 0) { $BadZones += @{ComputerName = $Server;ZoneName=$_.ZoneName;Adapters=$Adapters} } } } } } if ($BadZones.Count -gt 0) { Write-Warning "Found servers without AAAA records that have IPv6 enabled." } Write-Output -InputObject $BadZones } End { } } Function Set-DnsServerNotifySecondaryServers { <# .SYNOPSIS The Windows 2012 DNS Server must use DNS Notify to prevent denial of service through increase in workload. .DESCRIPTION The Set-DnsServerNotifySecondaryServers cmdlet ensures the Notify secondary servers is enabled for any DNS zone that allows zone transfers. .PARAMETER Forest The DNS Forest to configure. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerNotifySecondaryServers Ensures Notify is enabled for any DNS servers allowing zone transfers to secondaries. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 12/8/2015 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-SC-000027 Rule ID SV-73129r1 Vuln ID V-58699 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Setting secondary server notification settings." $Servers = Get-ForestDnsServers -Forest $Forest -Credential $Credential foreach ($Server in $Servers) { Get-SpecificServerDnsZones -ComputerName $Server -ZoneType Primary -Credential $Credential | ForEach-Object { if ($_.SecureSecondaries -ne "NoTransfer") { Set-DnsServerPrimaryZone -Name $_.ZoneName -ComputerName $Server -Notify Notify } } } Write-Host "Completed setting secondary server notification settings." } End { } } Function Remove-DnsServerWINSForwardLookup { <# .SYNOPSIS WINS lookups must be disabled on the Windows 2012 DNS Server. .DESCRIPTION The Remove-DnsServerWINSForwardLookup disabled WINS forward lookup on each DNS server in the forest. .PARAMETER Forest The DNS Forest to configure. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Remove-DnsServerWINSForwardLookup Disables WINS lookups on all DNS servers in the forest. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-SC-000006 Rule ID SV-73091r1 Vuln ID V-58661 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Setting WINS server settings." $Servers = Get-ForestDnsServers -Forest $Forest foreach ($Server in $Servers) { Get-SpecificServerDnsZones -ComputerName $Server -ZoneType Primary -LookupType Forward | ForEach-Object { #TODO: Set WINS Setting } } Write-Host "Completed WINS server settings." } End { } } Function Set-DnsServerCryptoFolderPermissions { <# .SYNOPSIS The Windows 2012 DNS Server must be configured to enforce authorized access to the corresponding private key. .DESCRIPTION The Set-DnsServerCryptoFolderPermissions sets %ALLUSERSPROFILE%\Microsoft\Crypto folder, subfolders, and files to Full Control for SYSTEM and Administrators and removes all other privileges. The owner for the folder, subfolders, and files is also set to BUILTIN\Administrators. .PARAMETER Forest The DNS Forest to configure. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerCryptoFolderPermissions Sets The permissions and owner for the crypto directory. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-IA-000006 WDNS-IA-000007 WDNS-IA-000008 Rule ID SV-73071r1 SV-73073r1 SV-73075r1 Vuln ID V-58641 V-58643 V-58645 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Setting Dns Server crypto folder owner and permissions." $Servers = Get-ForestDnsServers -Forest $Forest -Credential $Credential $Path = "$env:ALLUSERSPROFILE\Microsoft\Crypto" [System.Security.AccessControl.FileSystemAccessRule[]]$Rules = New-CryptoFolderAccessRuleSet foreach ($Server in $Servers) { Write-Host "Setting file permissions on $Server" $ServerPath = "\\$Server\" + $Path.Replace(":\","$\") Set-FileSecurity -Path $ServerPath -AccessRules $Rules -ReplaceAll -ForceChildInheritance Write-Host "Setting folder owner on $Server" Invoke-Command -ComputerName $Server -Scriptblock ${function:Set-Owner} -ArgumentList @($Path,"BUILTIN\Administrators",$true) } Write-Host "Completed setting crypto folder owner and permissions." } End { } } Function Set-DnsServerLogPermissions { <# .SYNOPSIS The Windows 2012 DNS Server logging criteria must only be configured by the ISSM or individuals appointed by the ISSM. .DESCRIPTION The cmdlet assigns specific access permissions for the DNS server logs The command must be run with Enterprise Admin credentials. .PARAMETER Forest The Forest in which to configure DNS servers. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerLogPermissions Sets the c:\windows\system32\winevt folder to the default permissions and forces inheritance on all log files. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-AU-000007 Rule ID SV-72983r1 Vuln ID V-58553 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Setting Dns Server log permissions." $Servers = Get-ForestDnsServers -Forest $Forest -Credential $Credential $Path = "$env:SYSTEMROOT\System32\Winevt\Logs" $Rules = New-EventLogAccessRuleSet foreach ($Server in $Servers) { Write-Host $Server $ServerPath = "\\$Server\" + $Path.Replace(":\","$\") Set-FileSecurity -Path $ServerPath -AccessRules $Rules -ReplaceAll -ForceChildInheritance } Write-Host "Completed setting Dns Server log permissions." } End { } } Function Set-DnsServerZoneTransfers { <# .SYNOPSIS The Windows DNS primary server must only send zone transfers to a specific list of secondary name servers. .DESCRIPTION The Set-DnsServerZoneTransfers cmdlet checks each DNS server in the forest to see if it has zone transfers enabled. If it does and are allowed "To any server", then the setting is changed to "Only to servers on the Name Servers tab". .PARAMETER Forest The DNS Forest to configure. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerZoneTransfers Sets all DNS servers in the forest that have zone transfers enabled to any server to only servers on the Name Servers tab. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-IA-000004 Rule ID SV-73067r1 Vuln ID V-58637 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Setting DNS Server Zone Transfer settings." $Servers = Get-ForestDnsServers -Forest $Forest -Credential $Credential foreach ($Server in $Servers) { Get-SpecificServerDnsZones -ComputerName $Server -ZoneType Primary | ForEach-Object { if ($_.SecureSecondaries -eq "TransferAnyServer") { Write-Warning "DNS Server $Server was set to transfer to any server, fixing..." Set-DnsServerPrimaryZone -Name $_.ZoneName -ComputerName $Server -SecureSecondaries TransferToZoneNameServer Write-Host "Done fixing $Server." } } } Write-Host "Completed setting DNS Server zone transfer settings" } End { } } Function Remove-DnsServerZoneIPv6LinkLocalAddresses { <# .SYNOPSIS Non-routable IPv6 link-local scope addresses must not be configured in any zone. .DESCRIPTION The Remove-DnsServerZoneIPv6LinkLocalAddresses cmdlet gets all AAAA records in each zone and removes any link-local scope addresses. .PARAMETER Forest The DNS Forest to configure. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Remove-DnsServerZoneIPv6LinkLocalAddresses Removes all IPv6 link-local addresses from all DNS Zones .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-CM-000026 Rule ID SV-73053r1 Vuln ID V-58623 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Removing IPv6 link local addresses from DNS." $Zones = @() Get-ForestDNSServers -Forest $Forest -Credential $Credential | ForEach-Object { $Zones += Get-DnsServerZone -ComputerName $_ -WarningAction SilentlyContinue | Where-Object {$_.IsReverseLookupZone -eq $false} } $Zones | Group-Object -Property ZoneName | ForEach-Object { $Zone = $_.Name $Zone try { $Server = Resolve-DnsName -Name $Zone -ErrorAction Stop | Select-Object -ExpandProperty PrimaryServer if ([System.String]::IsNullOrEmpty($Server)) { Write-Warning "PrimaryServer attribute was null, using the zone name for the server." $Server = $Zone } $RemovedRecords = Get-DnsServerResourceRecord -ZoneName $Zone -RRType AAAA -ComputerName $Server | Where-Object {$_.RecordData -match "^FE[89AB].*$"} | Remove-DnsServerResourceRecord -ComputerName $Zone -ZoneName $Zone -Force -Confirm:$false -PassThru if ($RemovedRecords.Count -gt 0) { Write-Warning "Removed the following records:" Write-Warning $RemovedRecords } else { Write-Host "No records to remove." } } catch [Exception] { Write-Warning "Could not get records for zone: $Zone`: $($_.ToString())" } } Write-Host "Completed removing IPv6 link local addresses." } End { } } Function Get-InactiveDnsServers { <# .SYNOPSIS The Windows 2012 DNS Servers zone files must have NS records that point to active name servers authoritative for the domain specified in that record. .DESCRIPTION The Get-InactiveDnsServers cmdlet gets all NS records for a forest and then tries to resolve the NS record hostname on that NS server. Any non-active DNS servers are returned. .PARAMETER Forest The DNS Forest to test against. .EXAMPLE PS C:\>Get-InactiveDnsServers Returns a list of any non-active DNS servers in the forest. .INPUTS System.String .OUTPUTS System.String[] .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-CM-000010 Rule ID SV-73023r1 Vuln ID V-58593 Severity CAT I #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty ) Begin { } Process { $InactiveServers = @() Write-Host "Getting all inactive DNS servers." Get-ForestDnsServers -Forest $Forest | ForEach-Object { $Server = $_ try { Resolve-DnsName -Name $_ -Server $_ -ErrorAction Stop | Out-Null } catch [Exception] { $InactiveServers += $Server } } Write-Output -InputObject $InactiveServers } End { } } Function Set-DnsServerDisableRootHints { <# .SYNOPSIS Forwarders on an authoritative Windows 2012 DNS Server, if enabled for external resolution, must only forward to either an internal, non-AD-integrated DNS server or to the DoD Enterprise Recursive Services (ERS). .DESCRIPTION The Set-DnsServerDisableRootHints cmdlet removes all root hints and disables using root hints on each DNS server in the forest. The command must be run with Enterprise Admin credentials. .PARAMETER Forest The DNS Forest to set the root hints settings on. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerDisableRootHints Disables root hints on all servers and removes root hints on all servers. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-CM-000004 WDNS-CM-000022 Rule ID SV-73011r1 SV-73045r1 Vuln ID V-58581 V-58615 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Disabling all DNS server root hints." $Servers = Get-ForestDnsServers -Forest $Forest -Credential $Credential foreach ($Server in $Servers) { Get-DnsServerRootHint -ComputerName $Server | Remove-DnsServerRootHint -ComputerName $Server -Force -Confirm:$false Invoke-Command -ComputerName $Server -ScriptBlock {Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters" -Name "IsSlave" -Value 1 } -Credential $Credential } } End { } } Function Set-DnsServerRecursionAndForwarders { <# .SYNOPSIS The Windows 2012 DNS Server must prohibit recursion on authoritative name servers for which forwarders have not been configured for external queries. .DESCRIPTION The Set-DnsServerRecursionAndForwarders cmdlet checks to see if forwarders are disabled, if they are it also disables recursion. The command must be run with Enterprise Admin credentials. .PARAMETER Forest The DNS Forest to set the recursion setting on. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerRecursionAndForwarders Disables recursion on all DNS servers without forwarders .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-CM-000003 Rule ID SV-73009r1 Vuln ID V-58579 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Setting DNS recursion and forwarders settings." $Servers = Get-ForestDnsServers -Forest $Forest -Credential $Credential foreach ($Server in $Servers) { $Forwarders = Get-DnsServerForwarder -ComputerName $Server if ($Forwarders.IPAddress.Count -eq 0) { Set-DnsServerRecursion -ComputerName $Server -Enable $false } } Write-Host "Completed setting recursions and forwarders." } End { } } Function Set-DnsServerZoneSecureUpdates { <# .SYNOPSIS The Windows 2012 DNS Server must restrict incoming dynamic update requests to known clients. .DESCRIPTION The Set-DnsServerZoneSecureUpdates cmdlet turns on secure updates only for all DNS servers in the forest. The command must be run with Enterprise Admin credentials. .PARAMETER Forest The DNS Forest to set secure updates on. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerZoneSecureUpdates Enforces secure updates on each primary zone in the current user forest. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-AC-000001 WDNS-IA-000001 Rule ID SV-72667r1 SV-73061r1 Vuln ID V-58237 V-58631 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Setting secure updates on Dns Servers." Get-ForestDnsZones -Forest $Forest -ZoneType Primary -DsIntegration DsIntegrated -Credential $Credential | ForEach-Object { Write-Host "Configuring secure dynamic updates on $($_.ZoneName)" $Zone = $_.ZoneName try { $Server = Resolve-DnsName -Name $_.ZoneName -ErrorAction Stop | Select-Object -ExpandProperty PrimaryServer if ([System.String]::IsNullOrEmpty($Server)) { Write-Warning "PrimaryServer attribute was null, using the zone name for the server." $Server = $_.ZoneName } Set-DnsServerPrimaryZone -Name $_.ZoneName -DynamicUpdate Secure -ComputerName $Server } catch [Exception] { Write-Warning "Error setting secure dynamic updates on $Zone`: $($_.ToString())" } } Write-Host "Completed setting secure updates." } End { } } Function Set-DnsServerLogging { <# .SYNOPSIS The Windows 2012 DNS Server must be configured to record, and make available to authorized personnel, who added/modified/deleted DNS zone information. .DESCRIPTION The cmdlet turns on logging and log rollover on every DNS server in the forest. The command must be run with Enterprise Admin credentials. .PARAMETER Forest The DNS Forest to set secure updates on. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerLogging Enables logging on every DNS server in the current user's forest. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-AU-000001 WDNS-AU-000005 WDNS-AU-000006 WDNS-AU-000007 WDNS-AU-000008 WDNS-AU-000010 WDNS-AU-000011 WDNS-AU-000012 WDNS-AU-000013 WDNS-AU-000014 WDNS-AU-000015 WDNS-SI-000009 Rule ID SV-72973r1 SV-72979r1 SV-72981r1 SV-72983r1 SV-72985r1 SV-72991r1 SV-72993r1 SV-72995r1 SV-72997r1 SV-72999r1 SV-73001r1 SV-73149r1 Vuln ID V-58543 V-58549 V-58551 V-58553 V-58555 V-58561 V-58563 V-58565 V-58567 V-58569 V-58571 V-58719 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Setting Dns Server logging." Get-ForestDnsServers -Forest $Forest -Credential $Credential | ForEach-Object { Write-Host $_ Set-DnsServerDiagnostics -ComputerName $_ -All $true Set-DnsServerDiagnostics -EnableLogFileRollover $true } Write-Host "Completed setting Dns Server logging." } End { } } Function Set-DnsServerVersionQuery { <# .SYNOPSIS The DNS Name Server software must be configured to refuse queries for its version information. .DESCRIPTION The Set-DnsServerVersionQuery cmdlet disables returning version information from a DNS query on all DNS servers in the Forest. The command must be run with Enterprise Admin credentials. .PARAMETER Forest The forest to configure. .PARAMETER Credential The credential to use, requires Enterprise Admin rights. .EXAMPLE PS C:\>Set-DnsServerVersionQuery Disables the return of version information from DNS queries. .INPUTS System.String .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 .FUNCTIONALITY STIG Microsoft Windows 2012 Server DNS V1R2 STIG ID WDNS-SI-000003 Rule ID SV-73167r1 Vuln ID V-58737 Severity CAT II #> Param( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { if (!(Test-IsEnterpriseAdmin -Credential $Credential)) { Write-Error "The cmdlet must be run with Enterprise Admin credentials." Exit 1 } Write-Host "Setting Dns Server version query settings." Get-ForestDnsServers -Forest $Forest -Credential $Credential | ForEach-Object { $Server = $_ Write-Host $Server try { Invoke-Command -ComputerName $_ -ScriptBlock {Set-ItemProperty -Path "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\DNS\\Parameters" -Name "EnableVersionQuery" -Value 0} -Credential $Credential } catch [Exception] { Write-Host "Error on $Server`: $($_.ToString())" } } Write-Host "Completed setting Dns Server version query settings." } End { } } Function Get-ForestDnsServers { <# .SYNOPSIS Finds all of the DNS servers for the current forest. .DESCRIPTION Finds all of the DNS servers registered as NS servers in the forest and returns an array of DNS names. .PARAMETER Forest Specify the forest to get the name servers from. .PARAMETER Credential The credential to use to query for the current AD Forest object. .EXAMPLE PS C:\>Get-ForestDnsServers Gets all of the DNS server in the current forest. .INPUTS System.String .OUTPUTS System.String[] .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 #> Param ( [Parameter(Position=0,ValueFromPipeline=$true)] [string]$Forest = [System.String]::Empty, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { try { Import-Module ActiveDirectory } catch [Exception] { Write-Warning "This cmdlet requires the Active Directory module." Exit 1 } } Process { if ($Forest -eq [System.String]::Empty) { if ($Credential -ne [PSCredential]::Empty) { $RootDomain = (Get-ADForest -Current $Credential.UserName -Credential $Credential).RootDomain } else { $RootDomain = (Get-ADForest -Current LoggedOnUser).RootDomain } } else { $RootDomain = $Forest } Write-Output -InputObject (Resolve-DnsName -Name $RootDomain -Type NS | Where-Object {![System.String]::IsNullOrEmpty($_.NameHost)} | Select-Object -ExpandProperty NameHost) } End { } } Function Get-ForestDnsZones { <# .SYNOPSIS Get all of the forward lookup zones in a forest. .DESCRIPTION The Get-ForestDnsZones cmdlet gets all of the primary forward lookup zones for a forest. .PARAMETER Forest The DNS Forest to search. .PARAMETER ZoneType Select from All, Primary, Seconday, or Stub. Defaults to All. .PARAMETER DsIntegration Select from All, DsIntegrated, or NonDsIntegrated. Defaults to All. .PARAMETER LookupType Select from All, Forward, or Reverse. Defaults to All. .PARAMETER Credential The credential to use. .EXAMPLE PS C:\>Get-ForestDnsZones Gets all of the dns zones in the current user's forest. .EXAMPLE PS C:\>Get-ForestDnzZones -ZoneType Primary -DsIntegration DsIntegrated -LookupType Forward Gets all primary, Active Directory integrated, forward lookup zones in the current user forest. .INPUTS None .OUTPUTS PSObject[] .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 #> Param( [Parameter(Position=0)] [string]$Forest = [System.String]::Empty, [Parameter(Position=1)] [ValidateSet("All","Primary","Secondary","Stub")] [string]$ZoneType = "All", [Parameter(Position=2)] [ValidateSet("All","DsIntegrated","NonDsIntegrated")] [string]$DsIntegration = "All", [Parameter(Position=3)] [ValidateSet("All","Forward","Reverse")] [string]$LookupType = "All", [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { } Process { $Zones = @() Get-ForestDNSServers -Forest $Forest -Credential $Credential | ForEach-Object { $Zones += Get-SpecificServerDnsZones -ComputerName $_ -ZoneType $ZoneType -DsIntegration $DsIntegration -LookupType $LookupType | Where-Object {-not $_.ZoneName.StartsWith("_")} } $Zones | Group-Object -Property ZoneName | Select-Object -Property Group | ForEach-Object { Write-Output -InputObject ($_.Group | Select-Object -First 1) } } End { } } Function Get-SpecificServerDnsZones { <# .SYNOPSIS Get all of the forward lookup zones in a forest. .DESCRIPTION The Get-ForestDnsZones cmdlet gets all of the primary forward lookup zones for a forest. .PARAMETER Forest The DNS Forest to search. .PARAMETER ZoneType Select from All, Primary, Seconday, or Stub. Defaults to All. .PARAMETER DsIntegration Select from All, DsIntegrated, or NonDsIntegrated. Defaults to All. .PARAMETER LookupType Select from All, Forward, or Reverse. Defaults to All. .EXAMPLE PS C:\>Get-SpecificServerDnsZones Gets all of the dns zones on the localhost. .EXAMPLE PS C:\>Get-SpecificServerDnsZones -ComputerName server01 Gets all of the dns zones on server01. .EXAMPLE PS C:\>Get-SpecificServerDnsZones -ComputerName server01 -ZoneType Primary -DsIntegration DsIntegrated -LookupType Forward Gets all primary, Active Directory integrated, forward lookup zones on server01. .INPUTS None .OUTPUTS PSObject[] .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 #> Param( [Parameter(Position=0)] [string]$ComputerName ="localhost", [Parameter(Position=1)] [ValidateSet("All","Primary","Secondary","Stub")] [string]$ZoneType = "All", [Parameter(Position=2)] [ValidateSet("All","DsIntegrated","NonDsIntegrated")] [string]$DsIntegration = "All", [Parameter(Position=3)] [ValidateSet("All","Forward","Reverse")] [string]$LookupType = "All" ) Begin {} Process { switch (($ZoneType + $DsIntegration + $LookupType)) { default {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue)} "AllAllAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue)} "AllAllForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.IsReverseLookupzone -eq $false})} "AllAllReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.IsReverseLookupzone -eq $true})} "AllDsIntegratedAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.IsDsIntegrated -eq $true})} "AllDsIntegratedForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $false})} "AllDsIntegratedReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.IsDsIntegrated -eq $true -and $_.IsReverseLookupzone -eq $true})} "AllNonDsIntegratedAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.IsDsIntegrated -eq $false})} "AllNonDsIntegratedForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.IsDsIntegrated -eq $false -and $_.IsReverseLookupZone -eq $false})} "AllNonDsIntegratedReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.IsDsIntegrated -eq $false -and $_.IsReverseLookupzone -eq $true})} "PrimaryAllAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Primary"})} "PrimaryAllForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsReverseLookup -eq $false})} "PrimaryAllReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsReverseLookup -eq $true})} "PrimaryDsIntegratedAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsDsIntegrated -eq $true})} "PrimaryDsIntegratedForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $false})} "PrimaryDsIntegratedReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $true})} "PrimaryNonDsIntegratedAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsDsIntegrated -eq $false})} "PrimaryNonDsIntegratedForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsDsIntegrated -eq $false -and $_.IsReverseLookupZone -eq $false})} "PrimaryNonDsIntegratedReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $true})} "SecondaryAllAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Secondary"})} "SecondaryAllForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Secondary" -and $_.IsReverseLookup -eq $false})} "SecondaryAllReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Secondary" -and $_.IsReverseLookup -eq $true})} "SecondaryDsIntegratedAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Secondary" -and $_.IsDsIntegrated -eq $true})} "SecondaryDsIntegratedForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Secondary" -and $_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $false})} "SecondaryDsIntegratedReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Secondary" -and $_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $true})} "SecondaryNonDsIntegratedAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Secondary" -and $_.IsDsIntegrated -eq $false})} "SecondaryNonDsIntegratedForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Secondary" -and $_.IsDsIntegrated -eq $false -and $_.IsReverseLookupZone -eq $false})} "SecondaryNonDsIntegratedReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Secondary" -and $_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $true})} "StubAllAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Stub"})} "StubAllForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Stub" -and $_.IsReverseLookup -eq $false})} "StubAllReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Stub" -and $_.IsReverseLookup -eq $true})} "StubDsIntegratedAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Stub" -and $_.IsDsIntegrated -eq $true})} "StubDsIntegratedForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Stub" -and $_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $false})} "StubDsIntegratedReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Stub" -and $_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $true})} "StubNonDsIntegratedAll" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Stub" -and $_.IsDsIntegrated -eq $false})} "StubNonDsIntegratedForward" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Stub" -and $_.IsDsIntegrated -eq $false -and $_.IsReverseLookupZone -eq $false})} "StubNonDsIntegratedReverse" {Write-Output (Get-DnsServerZone -ComputerName $ComputerName -WarningAction SilentlyContinue | Where-Object {$_.ZoneType -eq "Stub" -and $_.IsDsIntegrated -eq $true -and $_.IsReverseLookupZone -eq $true})} } } End {} } Function Set-ForestDnsServerScavenging { <# .SYNOPSIS Sets DNS record scavenging for all zones in the Forest. .DESCRIPTION Creates the File Access Rules for EventLog, System, and Administrators. .PARAMETER RefreshInterval Specifies the refresh interval as a TimeSpan object. During this interval, a DNS server can refresh a resource record that has a non-zero time stamp. Zones on the server inherit this value automatically. If a DNS server does not refresh a resource record that has a non-zero time stamp, the DNS server can remove that record during the next scavenging. Do not select a value smaller than the longest refresh period of a resource record registered in the zone. The minimum value is 0. The maximum value is 8760 hours (seven days). The default value is 7 days. .PARAMETER ScavengingInterval Specifies a length of time as a TimeSpan object. ScavengingInterval determines whether the scavenging feature for the DNS server is enabled and sets the number of hours between scavenging cycles. The default setting is 7. A setting greater than 0 enables scavenging for the server and sets the number of days, hours, minutes, and seconds (formatted as dd.hh:mm:ss) between scavenging cycles. The minimum value is 0. The maximum value is 365.00:00:00 (1 year). .EXAMPLE PS C:\>Set-ForestDnsServerScavenging Enables stale record scavenging .INPUTS System.TimeSpan, System.TimeSpan .OUTPUTS Microsoft.Management.Infrastructure.CimInstance#DnsServerScavenging[] .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 #> [CmdletBinding()] Param( [Parameter(Position=0)] [System.TimeSpan]$RefreshInterval = [System.TimeSpan]::FromDays(7), [Parameter(Position=1)] [System.TimeSpan]$ScavengingInterval = [System.TimeSpan]::FromDays(7), [Parameter()] [switch]$PassThru ) Begin { } Process { $Forest = Get-ADForest Write-Host "Setting DNS Server Scavenging." foreach ($Domain in $Forest.Domains) { Write-Host $Domain $Context = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext([System.DirectoryServices.ActiveDirectory.DirectoryContextType]::Domain, $Domain) $Servers = [System.DirectoryServices.ActiveDirectory.DomainController]::FindAll($Context) foreach ($Server in $Servers) { Write-Host $Server.Name try { $Scavenging = Set-DnsServerScavenging -ScavengingState $true -ApplyOnAllZones -ComputerName $Server.Name -RefreshInterval ([System.TimeSpan]::FromDays(7)) -ScavengingInterval ([System.TimeSpan]::FromDays(7)) -PassThru if ($PassThru) { Write-Output $Scavenging } } catch [Exception] { Write-Warning $_.Exception.Message } } } } End { } } Function New-EventLogAccessRuleSet { <# .SYNOPSIS Creates the File Access Rules for EventLog, System, and Administrators. .DESCRIPTION Creates the File Access Rules for EventLog, System, and Administrators. .EXAMPLE PS C:\>New-EventLogAccessRuleSet Creates the rule set. .INPUTS None .OUTPUTS System.Security.AccessControl.FileSystemAccessRule[] .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 #> [CmdletBinding()] Param( ) Begin { } Process { # NT Service\EventLog = S-1-5-80-880578595-1860270145-482643319-2788375705-1540778122 [System.Security.Principal.SecurityIdentifier]$NTServiceEventLogSid = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-80-880578595-1860270145-482643319-2788375705-1540778122") $Administrators = New-Object Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $null) $EventLog = New-Object Security.Principal.SecurityIdentifier($NTServiceEventLogSid) $System = New-Object Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::LocalSystemSid, $null) $AdministratorAce = New-Object System.Security.AccessControl.FileSystemAccessRule($Administrators, [System.Security.AccessControl.FileSystemRights]::FullControl, @([System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit), [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow) $EventLogAce = New-Object System.Security.AccessControl.FileSystemAccessRule($EventLog, [System.Security.AccessControl.FileSystemRights]::FullControl, @([System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit), [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow) $SystemAce = New-Object System.Security.AccessControl.FileSystemAccessRule($System, [System.Security.AccessControl.FileSystemRights]::FullControl, @([System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit), [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow) [System.Security.AccessControl.FileSystemAccessRule[]]$Rules = @($AdministratorAce, $EventLogAce, $SystemAce) Write-Output -InputObject $Rules } End { } } Function New-CryptoFolderAccessRuleSet { <# .SYNOPSIS Creates the File Access Rules for System and Administrators. .DESCRIPTION Creates the File Access Rules for System and Administrators. .EXAMPLE PS C:\>New-CryptoFolderAccessRuleSet Creates the rule set. .INPUTS None .OUTPUTS System.Security.AccessControl.FileSystemAccessRule[] .NOTES AUTHOR: Michael Haken LAST UPDATE: 2/28/2016 #> [CmdletBinding()] Param() Begin { } Process { [System.Security.Principal.SecurityIdentifier]$NTServiceEventLogSid = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-80-880578595-1860270145-482643319-2788375705-1540778122") $Administrators = New-Object Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $null) $System = New-Object Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::LocalSystemSid, $null) $AdministratorAce = New-Object System.Security.AccessControl.FileSystemAccessRule($Administrators, [System.Security.AccessControl.FileSystemRights]::FullControl, @([System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit), [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow) $SystemAce = New-Object System.Security.AccessControl.FileSystemAccessRule($System, [System.Security.AccessControl.FileSystemRights]::FullControl, @([System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit), [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow) [System.Security.AccessControl.FileSystemAccessRule[]] $Rules = @($AdministratorAce, $SystemAce) Write-Output -InputObject $Rules } End { } } |