Automatic alarm based on changes on screen

Have you ever had a situation where you have to wait on you computer for a ticket to appear in monitoring system, a message to arrive or anything similar? It can be annoying and you might loose your focus when you have to regularly check the system for new events.

I faced this same situation, and started thinking that there has to be a way to trigger an audible alarm somehow. Unfortunately in my case there was no API that could be used to implement alarms. I have to look for changes in a specific area on the screen. The idea is very simple; PowerShell -script running infinite loop, takes screenshot of specific area on your screen and then compares it to previous screenshot. If they are identical everything is okay, in the other case something has changed on the screen. In my case it means new ticket and the script starts to play an audible alarm.

Example run when something changes on the screen
$bounds = [Drawing.Rectangle]::FromLTRB(100, 300, 1800, 1400) # Set area to monitor dimensions here
$filePath = @("C:\Temp\screenshot.bmp","C:\Temp\screenshot2.bmp") #Screenshot filen ames

$continue = $true
$i=0;

[Reflection.Assembly]::LoadWithPartialName("System.Drawing")

# function for taking screenshots (from: https://stackoverflow.com/questions/2969321/how-can-i-do-a-screen-capture-in-windows-powershell)
function screenshot([Drawing.Rectangle]$bounds, $path) {
    $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
    $graphics = [Drawing.Graphics]::FromImage($bmp)
    $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
    $bmp.Save($path)
    $graphics.Dispose()
    $bmp.Dispose()
}

# infinite loop
while($continue)
{
    screenshot $bounds $filePath[$i % 2]

    #let's skip the first two rounds when the files do not exist yet and then start to compare
    if($i -gt 1)
    {
        if((Get-FileHash $filePath[0]).hash -eq (Get-FileHash $filePath[1]).hash)
        {
            #Files are the same
            $time = get-date -format "HH:mm:ss"
            Write-Host "$time Alive"
            Start-Sleep -Seconds 5 
        }
        else
        {

            #Files are different
            While($continue)
            {
                $time = get-date -format "HH:mm:ss"
                Write-Host "$time Alert!!" -ForegroundColor Red
                [console]::beep(1500,1000)
                Start-Sleep -Seconds 1 
            }
        }
    }

    $i++
}

The script comes without any guarantee, so please test that it works for your scenario first! I don’t know how accurate this method is exactly. It looks like you can move mouse on the screen without triggering the alarm, but opening up a menu triggers the alarm. In my case this was accurate enough.

Just save that script i.e. to alarm.ps1, set the coordinates and dimensions of the area on the screen to be monitored and run it. Sit back and relax, you will be alarmed when something changes.

I can easily come up with multiple ways of extending this. You could easily call a REST API, run Micrsoft Flow etc. when alarm is triggered.

Leave a Reply

Your email address will not be published. Required fields are marked *