DEV Community

Cover image for Building a Windows Laptop Monitoring Agent with Webex and Email Alerts
sam codex
sam codex

Posted on

Building a Windows Laptop Monitoring Agent with Webex and Email Alerts

Building a Windows Laptop Monitoring Agent with Webex and Email Alerts

I wanted to build a small security and device-monitoring tool for my Windows laptop.

The idea is simple:

  • When someone unlocks my laptop using a Windows PIN or password, I should receive a Webex message and an email.
  • When the laptop battery reaches 50% or lower while it is not charging, I should receive a Webex alert.
  • I should also be notified about important events such as failed login attempts, charger disconnection, sleep, resume, restart and shutdown.

Instead of creating a heavy employee-monitoring application, I decided to design a lightweight Windows background agent focused only on device security and power events.

What the System Should Do

The first version will monitor one Windows laptop.

It will detect the following events:

Event Webex Alert Email Alert
Laptop unlocked Yes Yes
Laptop locked Yes Yes
Battery reaches 50% or lower Yes No
Charger disconnected Yes No
Failed Windows login attempts Yes Yes
Laptop started Yes Optional
Laptop restarted Yes Optional
Laptop shut down Yes Optional
Laptop entered sleep mode Yes Optional
Laptop resumed from sleep Yes Optional
Unexpected shutdown detected Yes Yes

For battery monitoring, the alert should be sent only when:

Battery percentage <= 50%
AND
Laptop is not charging
Enter fullscreen mode Exit fullscreen mode

The notification must not repeat every few seconds while the battery remains below 50%.

Example Unlock Notification

When the laptop is unlocked, the Webex and email notification could look like this:

πŸ”“ LAPTOP UNLOCKED

Device: LENOVO-LAPTOP
Windows User: Sam
Date: 15 July 2026
Time: 11:35 AM
Battery: 76%
Power Status: Not charging
Local IP: 192.168.1.25
Network: Office Wi-Fi

Event: Windows PIN/password unlock
Enter fullscreen mode Exit fullscreen mode

This gives enough information to understand when, where and under which Windows account the laptop was accessed.

Example Battery Notification

πŸͺ« BATTERY WARNING

Device: LENOVO-LAPTOP
Windows User: Sam
Battery: 49%
Charging: No
Charger: Disconnected
Time: 3:20 PM

Please connect the laptop charger.
Enter fullscreen mode Exit fullscreen mode

I may also add secondary thresholds later:

50% - Warning
20% - Critical
10% - Emergency
Enter fullscreen mode Exit fullscreen mode

Proposed Architecture

The system will contain two main parts:

  1. A Windows monitoring agent installed on the laptop
  2. A backend API connected to Webex, email and PostgreSQL
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          Windows Laptop          β”‚
β”‚                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Windows Monitoring Agent   β”‚  β”‚
β”‚  β”‚                            β”‚  β”‚
β”‚  β”‚ - Unlock and lock events   β”‚  β”‚
β”‚  β”‚ - Battery monitoring       β”‚  β”‚
β”‚  β”‚ - Charger monitoring       β”‚  β”‚
β”‚  β”‚ - Sleep and resume events  β”‚  β”‚
β”‚  β”‚ - Failed login detection   β”‚  β”‚
β”‚  β”‚ - Local retry queue        β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚ HTTPS
                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          Backend API             β”‚
β”‚                                  β”‚
β”‚  - Validate device API key       β”‚
β”‚  - Store event in PostgreSQL     β”‚
β”‚  - Prevent duplicate alerts      β”‚
β”‚  - Send Webex direct message     β”‚
β”‚  - Send email notification       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚              β”‚
            β–Ό              β–Ό
      Webex Bot        SMTP Server
            β”‚              β”‚
            β–Ό              β–Ό
      Direct Message    Email Alert
Enter fullscreen mode Exit fullscreen mode

Why Use a C# Windows Service?

The laptop-side agent could technically be built using Node.js or Python.

However, I prefer C# and .NET for this part because it provides better native integration with Windows.

A .NET Windows Service can handle:

  • Windows session events
  • Automatic startup with Windows
  • Power mode changes
  • Sleep and resume events
  • Windows Event Log monitoring
  • Battery and charger information
  • Service recovery when the process crashes

The agent should run quietly in the background without requiring the user to manually start it.

Why Keep Notifications in the Backend?

The Windows agent should not directly contain sensitive credentials such as:

  • Webex bot access token
  • SMTP username
  • SMTP password
  • Database credentials

Instead, the agent should call a protected backend endpoint.

POST /api/device-alerts
Enter fullscreen mode Exit fullscreen mode

The backend will handle all external integrations.

This also makes it easier to change notification providers later without reinstalling the laptop agent.

For example, Webex could later be replaced or extended with:

  • Microsoft Teams
  • Slack
  • Telegram
  • Push notifications
  • SMS
  • WhatsApp

Example Event Payload

The Windows agent can send a JSON payload like this:

{
  "deviceId": "laptop-sam-001",
  "deviceName": "LENOVO-LAPTOP",
  "windowsUser": "Sam",
  "eventType": "DEVICE_UNLOCKED",
  "eventTime": "2026-07-15T11:35:00+05:30",
  "batteryPercentage": 76,
  "isCharging": false,
  "localIp": "192.168.1.25",
  "networkName": "Office Wi-Fi",
  "agentVersion": "1.0.0",
  "metadata": {
    "authenticationType": "WINDOWS_CREDENTIAL"
  }
}
Enter fullscreen mode Exit fullscreen mode

The backend can then store the event and decide which notification channels should be used.

Event Types

The first version may support these event types:

DEVICE_UNLOCKED
DEVICE_LOCKED
BATTERY_LOW
BATTERY_CRITICAL
CHARGER_CONNECTED
CHARGER_DISCONNECTED
DEVICE_SLEEP
DEVICE_RESUMED
DEVICE_STARTED
DEVICE_RESTARTED
DEVICE_SHUTDOWN
UNEXPECTED_SHUTDOWN
FAILED_LOGIN
AGENT_STARTED
AGENT_STOPPED
Enter fullscreen mode Exit fullscreen mode

Using standard event names will make the system easier to maintain and extend.

Battery Alert Logic

Battery alerts need careful state management.

Without it, the agent may send the same warning every 30 seconds.

A better approach is:

1. Check battery status every 30 seconds.

2. Check whether the laptop is charging.

3. If the laptop is not charging and battery is 50% or lower:
   - Check whether the 50% alert was already sent.
   - If not, send the alert.
   - Save the alert state locally.

4. Do not send the same alert again while the battery remains below 50%.

5. Reset the warning state after the battery charges above 55%.
Enter fullscreen mode Exit fullscreen mode

Pseudocode:

if (!battery.IsCharging && battery.Percentage <= 50)
{
    if (!state.LowBatteryAlertSent)
    {
        await alertService.SendAsync("BATTERY_LOW");
        state.LowBatteryAlertSent = true;
        await stateStore.SaveAsync(state);
    }
}

if (battery.IsCharging && battery.Percentage >= 55)
{
    state.LowBatteryAlertSent = false;
    await stateStore.SaveAsync(state);
}
Enter fullscreen mode Exit fullscreen mode

This avoids notification spam.

Detecting Failed Login Attempts

Failed Windows sign-in attempts should also be monitored.

However, sending an alert for every incorrect password attempt may create too many notifications.

A better rule would be:

First failed attempt:
Store it in the log.

Three failed attempts within five minutes:
Send a Webex and email warning.

Five or more failed attempts:
Send a high-priority security alert.
Enter fullscreen mode Exit fullscreen mode

Example:

🚨 MULTIPLE FAILED WINDOWS SIGN-INS

Device: LENOVO-LAPTOP
Attempted User: Sam
Failed Attempts: 3
Period: 5 minutes
Time: 2:14 AM

Multiple failed login attempts were detected.
Enter fullscreen mode Exit fullscreen mode

Handling Internet Disconnection

The laptop may be unlocked while the internet is unavailable.

The alert should not be lost.

The agent should maintain a small local offline queue.

Event detected
      |
      v
Is internet available?
      |
  β”Œβ”€β”€β”€β”΄β”€β”€β”€β”
  β”‚       β”‚
 Yes      No
  β”‚       β”‚
Send    Save locally
  β”‚       β”‚
  β”‚    Retry later
  β”‚       β”‚
  β””β”€β”€β”€β”¬β”€β”€β”€β”˜
      v
Mark as delivered
Enter fullscreen mode Exit fullscreen mode

SQLite or an encrypted local JSON store could be used for the first version.

When connectivity returns, pending alerts can be sent automatically.

Securing the Agent API

Every laptop should receive its own identity and API key.

Example agent configuration:

HEIDI_API_URL=https://heidi.example.com/api/device-alerts
DEVICE_ID=laptop-sam-001
DEVICE_API_KEY=generated-long-random-key
Enter fullscreen mode Exit fullscreen mode

The backend should implement:

  • HTTPS-only communication
  • One API key per device
  • Rate limiting
  • Request timestamp validation
  • Request signing
  • Duplicate-event protection
  • Device enable and disable controls
  • API-key rotation
  • Audit logging

A stronger implementation can sign each request using HMAC.

signature = HMAC_SHA256(
    requestBody + timestamp,
    deviceSecret
)
Enter fullscreen mode Exit fullscreen mode

The backend can reject requests with invalid signatures or old timestamps.

Database Structure

A basic PostgreSQL design could contain three tables.

Devices

CREATE TABLE devices (
    id UUID PRIMARY KEY,
    device_code VARCHAR(100) UNIQUE NOT NULL,
    device_name VARCHAR(255),
    assigned_user VARCHAR(255),
    api_key_hash TEXT NOT NULL,
    is_active BOOLEAN DEFAULT TRUE,
    last_seen_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW()
);
Enter fullscreen mode Exit fullscreen mode

Device Events

CREATE TABLE device_events (
    id UUID PRIMARY KEY,
    device_id UUID REFERENCES devices(id),
    event_type VARCHAR(100) NOT NULL,
    windows_user VARCHAR(255),
    battery_percentage INTEGER,
    is_charging BOOLEAN,
    local_ip VARCHAR(100),
    network_name VARCHAR(255),
    event_time TIMESTAMPTZ NOT NULL,
    metadata JSONB,
    created_at TIMESTAMPTZ DEFAULT NOW()
);
Enter fullscreen mode Exit fullscreen mode

Notification Logs

CREATE TABLE notification_logs (
    id UUID PRIMARY KEY,
    device_event_id UUID REFERENCES device_events(id),
    channel VARCHAR(50) NOT NULL,
    recipient TEXT,
    status VARCHAR(50),
    provider_response JSONB,
    sent_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW()
);
Enter fullscreen mode Exit fullscreen mode

Separating device events and notification logs helps track cases where the event was recorded successfully but the Webex or email delivery failed.

Backend Processing Flow

When the backend receives an event:

1. Validate the device ID.

2. Validate the API key or HMAC signature.

3. Reject expired requests.

4. Check for duplicate event IDs.

5. Store the event in PostgreSQL.

6. Load notification rules for the event type.

7. Send a Webex direct message.

8. Send email when required.

9. Store the delivery result.

10. Return the processing status to the laptop agent.
Enter fullscreen mode Exit fullscreen mode

Example response:

{
  "success": true,
  "eventId": "d25183bb-8f74-4623-9884-a291a5c82102",
  "notifications": {
    "webex": "sent",
    "email": "sent"
  }
}
Enter fullscreen mode Exit fullscreen mode

Future Admin Dashboard

Although the first release will monitor only one laptop, I want the database and API to support multiple company devices.

The dashboard could eventually show:

  • Online and offline devices
  • Current battery percentage
  • Charging status
  • Last unlock time
  • Current Windows username
  • Last IP address
  • Failed login attempts
  • Recent security alerts
  • Agent version
  • Notification delivery status
  • Device activation and deactivation
  • Per-device Webex recipients
  • Per-device email recipients

Example dashboard layout:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Laptop Monitoring Dashboard                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Online Devices: 8      Offline Devices: 2      Alerts: 4     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Device          User       Battery     Status      Last Eventβ”‚
β”‚--------------------------------------------------------------β”‚
β”‚ Sam-Laptop      Sam        74%          Online      Unlocked  β”‚
β”‚ Sales-Laptop-1  Arjun      48%          Warning     Battery   β”‚
β”‚ HR-Laptop-2     Priya      91%          Charging    Online    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Privacy Considerations

This project should remain a device-security tool, not hidden surveillance software.

It should not capture:

  • Keystrokes
  • Screenshots
  • Webcam images
  • Microphone audio
  • Personal files
  • Browser history
  • Application content
  • Private messages

For employee devices, it should be installed only on company-owned laptops with a clear monitoring policy and employee consent.

The goal is to monitor device health and security events, not private user activity.

Proposed Technology Stack

Windows Agent

C#
.NET 8
Windows Service
Windows Event Log
WMI or Windows Management APIs
SQLite for offline queue
HttpClient for API communication
Enter fullscreen mode Exit fullscreen mode

Backend

Node.js
Express or NestJS
PostgreSQL
Webex Bot API
SMTP or Microsoft 365 email
JWT or HMAC device authentication
Enter fullscreen mode Exit fullscreen mode

Dashboard

Next.js
React
Tailwind CSS
Recharts
Role-based access control
Enter fullscreen mode Exit fullscreen mode

Development Phases

Phase 1: Personal Laptop Agent

  • Detect Windows unlock and lock
  • Send Webex direct messages
  • Send email alerts
  • Detect battery level
  • Detect charger state
  • Add local logs
  • Start automatically with Windows

Phase 2: Security Events

  • Detect failed login attempts
  • Detect repeated failed logins
  • Detect sleep and resume
  • Detect startup and shutdown
  • Detect unexpected shutdowns
  • Add local retry queue

Phase 3: Multi-Device Backend

  • Device registration
  • Per-device API keys
  • PostgreSQL event storage
  • Notification rules
  • Delivery logs
  • Device heartbeat

Phase 4: Admin Dashboard

  • Device list
  • Battery and online status
  • Security alert history
  • Notification history
  • Device controls
  • Per-device settings

Phase 5: Enterprise Features

  • Remote configuration
  • Agent auto-update
  • Department-based devices
  • Alert escalation rules
  • Microsoft Teams and Slack support
  • Reporting and analytics
  • Device health score

Final Thoughts

This started as a simple requirement:

Send me a Webex message and an email when my laptop is unlocked.

But it can grow into a useful lightweight device security and monitoring platform.

The most important design decision is keeping the Windows agent simple.

The agent should only detect events, collect limited device information and securely send data to the backend. All notification logic, credentials, logging and administration should remain on the server.

This provides better security, easier maintenance and a clear path from monitoring one personal laptop to managing multiple company devices.

I plan to start with the Windows unlock and battery monitoring features, then gradually add the security events, backend dashboard and multi-device support.

Tags

#windows
#dotnet
#csharp
#node
#webex
#security
#automation
#postgresql
#devops
#programming
Enter fullscreen mode Exit fullscreen mode

Top comments (0)