We recently deployed Windows DirectAccess for one of our clients and wanted to monitor the deployment. In particular I was interested in the number of active DirectAccess sessions and if any errors were detected. The Remote Access MMC snap-in (in Server 2012 R2) has a great status page that runs down all of DirectAccess’ components and reports any errors that are detected.
You can basically assume that if any of these are red you’re going to have an issue. With PRTG the number of components in an error state could be a channel in a sensor which we could monitor and report on (for instance if the number of errors is greater than 0). Similarly another channel could be the number of sessions.
DirectAccess comes loaded with a few PowerShell cmdlets for monitoring and reporting on its status. In particular Get-RemoteAccessHealth and Get-RemoteAccessConnectionStatisticsSummary will give you a lot of information. In order to make that data useful for PRTG we want to strip that output down from something like this (the raw output of Get-RemoteAccessHealth)
Component RemoteAccessServer HealthState TimeStamp Id OperationStatus
--------- ------------------ ----------- --------- -- ---------------
Server localhost OK 1/27/2015 11:05:4...
6to4 localhost OK 1/27/2015 11:01:0...
Vpn Addressing localhost Disabled 1/27/2015 11:01:0...
Network Security localhost OK 1/27/2015 11:01:0...
Dns localhost OK 1/27/2015 11:05:4...
IP-Https localhost OK 1/27/2015 11:01:0...
Nat64 localhost OK 1/27/2015 11:01:0...
Dns64 localhost OK 1/27/2015 11:01:0...
IPsec localhost OK 1/27/2015 11:01:0...
Kerberos localhost OK 1/27/2015 11:01:0...
Domain Controller localhost OK 1/27/2015 11:01:0...
Management Servers localhost Disabled 1/27/2015 11:01:0...
Network Location ... localhost OK 1/27/2015 11:05:4...
Otp localhost Disabled 1/27/2015 11:01:0...
High Availability localhost Disabled 1/27/2015 11:01:0...
Isatap localhost Disabled 1/27/2015 11:01:0...
Vpn Connectivity localhost Disabled 1/27/2015 11:01:0...
Teredo localhost Disabled 1/27/2015 11:01:0...
Network Adapters localhost OK 1/27/2015 11:01:0...
Services localhost OK 1/27/2015 11:05:4...
To literally just the number of components with a HealthState of “error”. This gives us our first sensor channel, “error count”. Our second channel is similar, I just want know how many active DirectAccess sessions we have which involves stripping down the output of Get-RemoteAccessConnectionStatisticsSummary
TotalConnections : 8
TotalDAConnections : 8
TotalVpnConnections : 0
TotalUniqueUsers :
MaxConcurrentConnections : 19
TotalCumulativeConnections : 2550
TotalBytesIn : 4024483872
TotalBytesOut : 8136960808
TotalBytesInOut : 12161444680
To just the number of TotalDAConnections.
The full PowerShell script is below
Write-Host "<?xml version=`"1.0`" encoding=`"Windows-1252`" ?>"
Write-Host "<prtg>"
Try
{
$daErrorCount = (Get-RemoteAccessHealth -ComputerName SERVER | Where-Object {$_.HealthState -match 'Error'} | measure).count
$daUserCount = Get-RemoteAccessConnectionStatisticsSummary -ComputerName SERVER | Select -ExpandProperty TotalDAConnections
Write-Host "<result>"
Write-Host "<channel>DirectAccess Errors</channel>"
Write-Host "<value>$daErrorCount</value>"
Write-Host "</result>"
Write-Host "<result>"
Write-Host "<channel>DirectAccess Sessions</channel>"
Write-Host "<value>$daUserCount</value>"
Write-Host "</result>"
}
Catch [system.exception]
{
Write-Host "<error>1</error>"
Write-Host "<text>$_</text>"
}
Write-Host "</prtg>"
This results in a PRTG sensor with the following channel setup
The key lines here that give PRTG its value for the channels are
(Get-RemoteAccessHealth -ComputerName SERVER | Where-Object {$_.HealthState -match 'Error'} | measure).count
and
Get-RemoteAccessConnectionStatisticsSummary -ComputerName SERVER | Select -ExpandProperty TotalDAConnections
The first is getting our error count. As we move down the command we’re filtering the output of Get-RemoteAccessHealth for the HealthState column and then looking for any matches on the value “Error”. Both measure and count are needed to just return in integer, measure by itself returns this.
Count : 0
Average :
Sum :
Maximum :
Minimum :
Property :
Get-RemoteAccessHealth is returning a table and PowerShell makes it pretty easy to search through it like you might search for something in Excel. Get-RemoteAccessConnectionStatisticsSummary is a little trickier. Its returning a list and if you try to use the same method of stripping its output as Get-RemoteAccessHealth that won’t work. However Select -ExpandProperty will. This took me a while to figure out until I piped the output of each command through Get-Member which reveals the Object-Types being returned. This article was very helpful during that process.
The rest of the script is pretty standard fare for PRTG’s custom XML sensors (a lot of great examples can be found here). The entire script is returning back to PRTG something that looks like this
<?xml version=`"1.0`" encoding=`"Windows-1252`" ?>
<prtg>
<result>
<channel>DirectAccess Errors</channel>
<value>0</value>
</result>
<result>
<channel>DirectAccess Sessions</channel>
<value>10</value>
</result>
</prtg>
Which is just the XML formatting that PRTG needs to construct a sensor. The try statement is used to catch any errors since PowerShell can be annoying to get setup for remote monitoring and I wanted to make sure that any issues with the sensor itself were handled by PRTG instead of the sensor silently failing (for instance returning 0 for a channel, which wouldn’t necessarily set off any alarms but might happen if one of our cmdlets failed)