Global Test Configured Forwarder Health

Microsoft.Windows.DNSServer.2016.Task.HealthCheck.ConfiguredForwarder.Global (Task)

Checks that all the Forwarders from each discovered DNS Server are responsive. At least one Windows 2016 and 1709+ DNS Server is required for execution of the task.

Element properties:

TargetMicrosoft.Windows.DNSServer.2016.Group
AccessibilityInternal
CategoryCustom
EnabledTrue
RemotableFalse
Timeout300

Member Modules:

ID Module Type TypeId RunAs 
PA ProbeAction Microsoft.Windows.DNSServer.2016.HtmlReporterPowershellProbe.PA Microsoft.Windows.DNSServer.2016.ActionAccount

Source Code:

<Task ID="Microsoft.Windows.DNSServer.2016.Task.HealthCheck.ConfiguredForwarder.Global" Accessibility="Internal" Target="Microsoft.Windows.DNSServer.2016.Group" Enabled="true" Timeout="300" Remotable="true">
<Category>Custom</Category>
<ProbeAction ID="PA" TypeID="Microsoft.Windows.DNSServer.2016.HtmlReporterPowershellProbe.PA" RunAs="Microsoft.Windows.DNSServer.2016.ActionAccount">
<ScriptName>Microsoft.Windows.Server.10.0.HealthCheck.ConfiguredForwarder.Global.Task.Script.ps1</ScriptName>
<ScriptBody><Script>

param ([String] $OutputFolder)
$SCRIPT_NAME = "HealthCheckConfiguredForwarderServer10.0.Global"
$ErrorActionPreference = "Stop"

Function Save-TaskHtmlReport
{
param (
[string] $path,
[string] $reportName,
[string] $html
)

if(Test-Path -Path $path -PathType Container)
{
try
{
$dt = Get-Date
$fileName = $reportName + "_" + $dt.ToString("dd-MM-yyyy_HH-mm-ss.ff")+'.htm'
$filePath = Join-Path -Path $path -ChildPath $fileName

$file = New-Item -Path $filePath -ItemType "file" -ErrorAction:Stop
Add-Content -Path $filePath -Value $html -ErrorAction:Stop
Write-Host "Report path: " $filePath
}
catch
{
Write-Host "Report writing failed, .html report will not be written to output folder. You can find it below."
Write-Host
Write-Host $resultHtml
}
}
else
{
Write-Host "Output folder is invalid. Html report will not be written to output folder"
}
}

Function Run-SCOMParameterizedTask
{
param (
[string] $taskName,
[string] $targetClass,
[string] $Parameter1,
[string] $Parameter2,
[string] $Parameter3,
[string] $OutputFolder,
[string] $ReportName


)
try
{
$task = Get-SCOMTask -Name $taskName
$class = Get-SCOMClass -Name $targetClass
$targets = Get-SCOMClassInstance -Class $class

if($targets -ne $null)
{
if($targets.Count -eq 1)
{
$selectedTarget = $targets
}
else
{
$selectedTarget = $targets[0]
}


$overrides = New-Object -TypeName Hashtable
if($Parameter1 -ne $null -and $Parameter1 -ne "") { $overrides.Add("Parameter1",$Parameter1) }
if($Parameter2 -ne $null -and $Parameter2 -ne "") { $overrides.Add("Parameter2",$Parameter2) }
if($Parameter3 -ne $null -and $Parameter3 -ne "") { $overrides.Add("Parameter3",$Parameter3) }

# very dirty trick - remove in next version by passing timeout into script
if ($taskName -eq 'Microsoft.Windows.DNSServer.2016.Task.HealthCheck.ConfiguredRootHints')
{
$calcTimeout = $targets.Count * 1000
$overrides.Add("TimeoutSeconds",$calcTimeout.ToString())
}
else
{
$calcTimeout = 250
}

if($overrides.Count -eq 0)
{
$taskResultSnapshot = Start-SCOMTask -Instance $selectedTarget -Task $task
}
else
{
$taskResultSnapshot = Start-SCOMTask -Instance $selectedTarget -Task $task -Override $overrides
}



for ($i = 1; $i -le $calcTimeout; $i++)
{
$taskResult = Get-SCOMTaskResult -Id $taskResultSnapshot.Id
if ($taskResult.Status -eq [Microsoft.EnterpriseManagement.Runtime.TaskStatus]::Started `
-or $taskResult.Status -eq [Microsoft.EnterpriseManagement.Runtime.TaskStatus]::Scheduled)
{
#Write-Host "Remote task " $taskResult.Status
Start-Sleep -Seconds 1
}
else
{
break
}
}

if($taskResult.Status -eq [Microsoft.EnterpriseManagement.Runtime.TaskStatus]::Succeeded)
{


if($OutputFolder -eq $null -or $OutputFolder -eq "")
{
# here we do not remove linebreaks
$xml = [xml]($taskResult.Output)
if($xml.DataItem.StdOut.InnerText -ne $null)
{
$str = $xml.DataItem.StdOut.InnerText
$str = $str.Replace("&amp;amp;lt;","&lt;")
$str = $str.Replace("&amp;amp;gt;","&gt;")
$str = $str.Replace("&amp;lt;","&lt;")
$str = $str.Replace("&amp;gt;","&gt;")
$resultHtml = $str
}
else
{
Write-Host "There are no Task Output"
}


#Write-Host "OutputFolder parameter is not specified, task report will not be written."
Write-Host $resultHtml
}
else
{
$xml = [xml]($taskResult.Output)
if($xml.DataItem.StdOut.InnerText -ne $null)
{
$str = $xml.DataItem.StdOut.InnerText
$str = $str.Replace("`n","");
$str = $str.Replace("`r","");
$str = $str.Replace("&amp;amp;lt;","&lt;")
$str = $str.Replace("&amp;amp;gt;","&gt;")
$str = $str.Replace("&amp;lt;","&lt;")
$str = $str.Replace("&amp;gt;","&gt;")
$resultHtml = $str
}
else
{
Write-Host "There are no Task Output"
}

Write-Host "OutputFolder: " $OutputFolder
try
{
Save-TaskHtmlReport -path $OutputFolder -reportName $ReportName -html $resultHtml
}
catch
{
Write-Host "Report writing failed, .html report will not be written to output folder. You can find it below."
Write-Host
Write-Host $resultHtml
}

}
}
else
{
if($taskResult.Status -eq [Microsoft.EnterpriseManagement.Runtime.TaskStatus]::Started)
{
Write-Host "Remote task was timed out. Report will not be written to output folder."
}
else
{
$res = $taskResult.Status
Write-Host "Remote task failed with status " $res
}

}
}
else
{
Write-Host 'No objects to perform complex tasks. Computer with DNS Server role required.'
}

}
catch
{
write-Host "Error!"
write-Host $_.Exception.Message
}
}

Function Import-GlobalTaskCmdlets()
{

$SCOMPowerShellKey = "HKLM:\SOFTWARE\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2"
$SCOMModulePath = (Get-ItemProperty $SCOMPowerShellKey).InstallDirectory
if ($true -eq [string]::IsNullOrEmpty($SCOMModulePath))
{
$ErrorMessage = "Path to SCOM cmdlets not found in registry."
Write-Host $ErrorMessage
exit
}

$SCOMModulePath = Join-Path $SCOMModulePath "OperationsManager"

try
{

Import-module $SCOMModulePath

}
catch [System.IO.FileNotFoundException]
{
$ErrorMessage = "SCOM cmdlets do not exist."
Write-Host $ErrorMessage
exit
}
catch
{
$ErrorMessage = $_.Exception.Message
Write-Host "Cannot import SCOM cmdlets"
Write-Host $ErrorMessage
exit
}


}

Import-GlobalTaskCmdlets

for ($tryIndex = 1; $tryIndex -le 10; $tryIndex++)
{
try{
$targets = Get-SCOMClass -Name 'Microsoft.Windows.DNSServer.2016.Server' | Get-SCOMClassInstance
break
}
catch { Start-Sleep -Seconds 1 }
}

if($targets -ne $null)
{
if($targets.Count -eq 1)
{
$servers = $targets.'[Microsoft.Windows.Computer].PrincipalName'.Value
}
else
{
foreach ($tmpObject in $targets)
{
$servers += $tmpObject.'[Microsoft.Windows.Computer].PrincipalName'.Value + ";"
}
}

#Write-Host $servers
Run-SCOMParameterizedTask -taskName 'Microsoft.Windows.DNSServer.2016.Task.HealthCheck.ConfiguredForwarder' `
-targetClass 'Microsoft.Windows.DNSServer.2016.Healthcheck.TaskTarget' `
-Parameter1 $servers `
-OutputFolder $OutputFolder `
-ReportName $SCRIPT_NAME
}
else
{
Write-Host "No DNS Servers 2016 objects found."
}
</Script></ScriptBody>
<OutputFolder>c:\</OutputFolder>
<TimeoutSeconds>300</TimeoutSeconds>
</ProbeAction>
</Task>