In many SME organizations, tracking the indoor climate monitor devices becomes difficult when the number of devices increases.

These devices supports multiple interfaces such as web, SNMP, e-mail etc. Integrating SNMP with network monitor application provides a central platform for reporting. But without network monitoring software, it is difficult to monitor these devices.

One other way is to use powershell to collect the information from the web interface of these devices.

Use Case: Automate and Consolidate Temperature Sensors Monitoring Using PowerShell

Mail from CIO: There has been an incident where the AC failed and temperature sensors started firing alerts. Luckily, the team was able to solve the problem except for one which went unnoticed as the mailbox was bombarded with the alerts. We need to have a consolidated view and alert mechanism of temperature/humidity monitoring sensors located across different location. Lets work on this.

Solution: The temperature sensors has SNMP builtin with which we can configure in any monitoring software, but it needs licenses and there comes the factor of cost. An alternative way is to use Powershell and query the temperature/humidity information from the web interface or Xml response (if the device supports). For the centralized report, we will have to maintain device database in a CSV file(format is given in the script), powershell will query each device for temperature/humidity information and then combine all the information to an HTML file and mail to the operation/admins provided the conditions are met.

Steps:

  1. Read the CSV file to get hardware IP, status, location, admin information
  2. Loop through each device and query for the temperature and humidity data (either HTML or XML)
  3. Merge all data together as HTML
  4. Shoot the mail with the HTML as body or as attachment if the threshold conditions are met (the computer IP should be whitelisted in the SMTP server)
  5. Schedule the script every 15 minutes to scan all the temperature monitor sensors

Note: Below sample code is good if the number of devices are less. When the number of devices are more and scanning frequency is high, then it has to be handled in parallel processing method. Below sample process the sensors one after the other.

The HTML content varies based on devices

PowerShell Script for automating Temperature/Humidity Sensor monitoring

Below Code uses
 · PowerShell Web Methods, XML functions
 · HTML 
 · CSS Styles
 · SMTP mail trigger 
#######################TEMPERATURE MONITOR REPORTER############################
# CSV STRUCTURE
# IP,Status,Location,AdminInfo
#————————————-
#IP – IP address of the device
#Status – 0 or 1 | flag for whether to scan the device
#Location – Area where device is located
#AdminInfo – Details of Site Administrator
################################

#

##############FUNCTIONS##################

#This method will convert the list to HTML
function frameHTML($__Sensors) {
    $__htmlReport = $__Sensors | ConvertTo-Html
    foreach ($__text in $__htmlReport) {
        if ($__text.substring(1, 2) -eq “tr”) {
            $__temp = ($__htmlReport[$__count].Split(“>”)[6]).split(“<“)[0]
            if ($__heading -eq 0) {
                $__htmlReport[$__count] = $__htmlReport[$__count].Replace(“<tr>”, ‘<tr style=”background-color:lightgreen”>’)
                $__heading = 1
            }

            if ($__temp -eq “DOWN”) {
                $__htmlReport[$__count] = $__htmlReport[$__count].Replace(“<tr>”, ‘<tr style=”background-color:yellow”>’)
            }
            elseif ($__temp -eq “Temperature”) {
                #$__htmlReport[$__count] = $__htmlReport[$__count].Replace(“<tr>”, ‘<tr style=”background-color:blue”>’)
            }

            elseif ([int]$__temp -gt $__MailTriggerTemperatureCritical) {
                $__htmlReport[$__count] = $__htmlReport[$__count].Replace(“<tr>”, ‘<tr style=”background-color:red”>’)
            }

        }
        if ($__text.Contains(“table”)) {
            $__htmlReport[$__count] = $__htmlReport[$__count].Replace(“<table>”, ‘<p style=”text-align: center;”><span style=”text-decoration: underline;”><strong>Temperature Monitor</strong></span></p><table border=”1″>’)
        }
        if ($__text.Contains(“/table”) -and $__Sensors.count -gt 0) {

            $__footerText = @”
</table>
<p>Note: Rows in <mark class=”red”>RED</mark>/<mark class=”yellow”>YELLOW</mark> color, if alerts are fired continuously every 15 minutes, Please inform Admins</p>
<table style=”width: 298px;” border=”1″>
<tbody>
<tr>
<td style=”width: 30px; background: red”>RED</td>
<td style=”width: 177px;”>High Temperature Alert</td>
</tr>
<tr>
<td style=”width: 30px; background:yellow”>YELLOW</td>
<td style=”width: 177px;”>Device Offline</td>
</tr>
</tbody>
</table>

“@
            $__htmlReport[$__count] = $__htmlReport[$__count].Replace(“</table>”, $__footerText)
        }
        if ($__text.Contains(“/head”)) {
            $__CSS = @”
</head>
<style type=”text/css”>
mark.red {
background: red;
font-weight:bold;
font-style:italic;
}

mark.yellow {
background: yellow;
font-weight:bold;
font-style:italic;
}
</style>

“@
            $__htmlReport[$__count] = $__htmlReport[$__count].Replace(“</head>”, $__CSS)
        }
        $__count++
    }
    $__htmlReport | Out-File “C:\Script\TemperatureMonitorDaemon.htm”
}


#This function will trigger the mail
function triggerMail() {
    $fromaddress = “[email protected]”
    $toaddress = “[email protected]”
    $CCaddress = “[email protected], [email protected]”
    $Bccaddress = “[email protected], [email protected]”
    $Subject = “Temperature Monitor”
    $body = get-content “C:\Script\TemperatureMonitorDaemon.htm”
    # $attachment = “C:\Script\TemperatureMonitorDaemon.htm”

    $smtpserver = “smptserver.domain.local”

    $message = new-object System.Net.Mail.MailMessage
    $message.From = $fromaddress
    #$message.To.Add($toaddress)
    #$message.CC.Add($CCaddress)
    $message.Bcc.Add($Bccaddress)
    $message.IsBodyHtml = $True
    $message.Subject = $Subject

    $message.body = $body
    $smtp = new-object Net.Mail.SmtpClient($smtpserver)
    $smtp.Send($message)
}

##############END OF FUNCTIONS##################


#This variable will hold the temperature data
$__Sensors = @()

#Threshold for appearing in the mail
$__MailTriggerTemperature = 20

#Threshold for appearing in the mail with red highlight
$__MailTriggerTemperatureCritical = 25

#To keep count of the devices where temperature is above trigger
$__count = 0
$__heading = 0

#importing the hardware ip from CSV file
$__monitors = Import-Csv “C:\Script\DeviceList.txt”
#Filter only devices where flag is 1
$__monitors = $__monitors | where { $_.Status -eq 1 }

#looping through each ip address
$__monitors | % {

    $__DeviceDetails = New-Object PSObject

    #checking for the network connectivity
    if (test-connection $_ -Count 2 -ErrorAction SilentlyContinue) {
        #reading web response data
        $DeviceContent = Invoke-WebRequest -Uri “http://$_/ -TimeoutSec 5 -ErrorAction SilentlyContinue -WarningAction SilentlyContinue

#reading XML data — note that the url is different
$__dev =Invoke-WebRequest -uri “http://$_/data.xml -TimeoutSec 5 -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
        $__xmls = [xml]$__dev.content

        $__TempXML = ($__xmls.server.devices.device.field | where { $_.key -eq “TempC” }).value
        $__HumidityXML = ($__xmls.server.devices.device.field | where { $_.key -eq “Humidity” }).value

        #if the read value is greater than the trigger mentioned in the declared values, then add the details to the list
        if ($__TempXML -gt $__MailTriggerTemperature) {

            $__SensorIP = $_.IP
            #$__SensorData = ($DeviceContent.AllElements | where {$_.class -eq “sensordata_ok”}).innerText
            #$__SensorInfo = ($DeviceContent.AllElements | where {$_.id -eq “footer”} ).outerText

            #if the location is configured in the device and has to be fetched from the same
            #$__Location = ($__SensorInfo.split(“`n”)[0])
            #$__Location = $__Location.Substring(($__Location.IndexOf(“:”) + 2), ($__Location.Length – $__Location.IndexOf(“:”) – 2))

            #info from CSV file
            $__Location = $_.Location
            $__AdminDetails = $_.AdminInfo

            #Adding the sensor information to object
            $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Monitor_IP -Value $__SensorIP
            $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Humidity -Value $__HumidityXML
            $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Temperature -Value $__TempXML
            $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Info -Value $__Location
            $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Admin -Value $__AdminDetails
        }
    }
    else {
        #if the device is not rechable, the same is marked as DOWN
        $__DeviceDetails = New-Object PSObject
        $__SensorIP = $_.IP
        $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Monitor_IP -Value $__SensorIP
        $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Humidity -Value “DOWN”
        $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Temperature -Value “DOWN”
        $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Info -Value “DOWN”
        $__DeviceDetails | Add-Member -MemberType NoteProperty -Name Admin -Value “DOWN”
    }
    #Adding the object to list
    $__Sensors += $__DeviceDetails
}

#convert list to html
frameHTML($__Sensors)


#If the temperature from devices are greater than the trigger temperature, the mails are fired
if ($__Sensors.Count -gt 0) {
    triggerMail
}

Sample Output:

Disclaimer: Please take this only as a reference. I am not responsible for any damage caused to your environment. TEST your code before deploying in production.

Hope it will be helpful for you …