CLAUDE: Add Windows desktop monitoring system with Discord notifications

- Complete PowerShell-based monitoring solution for Windows reboots
- Detects startup, shutdown, and unexpected restart events
- Rich Discord notifications with color-coded alerts
- Automatic reboot reason detection (Windows Update, power loss, user-initiated)
- Task Scheduler integration for reliable event monitoring
- Comprehensive setup instructions and troubleshooting guide

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Cal Corum 2025-08-11 09:29:09 -05:00
parent 26f5b82afa
commit daedfb298c
6 changed files with 572 additions and 0 deletions

View File

@ -68,6 +68,7 @@ When working in specific directories:
- Load: `reference/` (relevant troubleshooting guides) - Load: `reference/` (relevant troubleshooting guides)
- Load: `scripts/*/README.md` (subsystem-specific documentation) - Load: `scripts/*/README.md` (subsystem-specific documentation)
- Context: Active operational scripts - treat as production code - Context: Active operational scripts - treat as production code
- Note: Windows desktop monitoring system available in `scripts/monitoring/windows-desktop/`
### Keyword Triggers ### Keyword Triggers
When user mentions specific terms, automatically load relevant docs: When user mentions specific terms, automatically load relevant docs:
@ -125,6 +126,11 @@ When user mentions specific terms, automatically load relevant docs:
- Load: `scripts/tdarr/README.md` (for automation and scheduling) - Load: `scripts/tdarr/README.md` (for automation and scheduling)
- Note: Gaming-aware scheduling system with configurable time windows available - Note: Gaming-aware scheduling system with configurable time windows available
**Windows Monitoring Keywords**
- "windows reboot", "discord notification", "system monitor", "windows desktop", "power outage", "windows update"
- Load: `scripts/monitoring/windows-desktop/README.md`
- Note: Complete Windows desktop monitoring with Discord notifications for reboots and system events
### Priority Rules ### Priority Rules
1. **File extension triggers** take highest priority 1. **File extension triggers** take highest priority
2. **Directory context** takes second priority 2. **Directory context** takes second priority
@ -147,6 +153,8 @@ When user mentions specific terms, automatically load relevant docs:
/reference/ # Troubleshooting, cheat sheets, fallback info /reference/ # Troubleshooting, cheat sheets, fallback info
/scripts/ # Active scripts and utilities for home lab operations /scripts/ # Active scripts and utilities for home lab operations
├── tdarr/ # Tdarr automation with gaming-aware scheduling ├── tdarr/ # Tdarr automation with gaming-aware scheduling
├── monitoring/ # System monitoring and alerting
│ └── windows-desktop/ # Windows reboot monitoring with Discord notifications
└── <future>/ # Other organized automation subsystems └── <future>/ # Other organized automation subsystems
``` ```

View File

@ -0,0 +1,125 @@
# Windows Desktop Monitoring System
A comprehensive solution for monitoring Windows machine reboots and system events with Discord notifications.
## Overview
This system monitors Windows desktop/workstation machines for:
- System startups (normal and unexpected)
- System shutdowns (planned and unplanned)
- Reboot reasons (Windows Updates, power outages, user-initiated)
- System uptime and boot statistics
## Files
### Core Components
- **`windows-reboot-monitor.ps1`** - Main PowerShell monitoring script
- **`windows-reboot-task-startup.xml`** - Task Scheduler configuration for startup monitoring
- **`windows-reboot-task-shutdown.xml`** - Task Scheduler configuration for shutdown monitoring
- **`windows-setup-instructions.md`** - Complete installation and configuration guide
## Features
### Notification Types
- 🟢 **Normal Startup** - System booted normally after planned shutdown
- 🔴 **Unexpected Restart** - System recovered from power loss, crash, or forced reboot
- 🟡 **Planned Shutdown** - System is shutting down gracefully
### Information Captured
- Computer name and timestamp
- Boot/shutdown reasons (Windows Update, power issues, user actions)
- System uptime duration
- Boot counter for tracking restart frequency
- Event log analysis for root cause determination
### Technical Details
- **PowerShell Script**: Robust error handling and logging
- **Task Scheduler Integration**: Runs automatically on system events
- **Discord Webhooks**: Rich embedded notifications with color coding
- **Event Log Monitoring**: Analyzes Windows System logs for detailed context
- **Configuration Management**: Persistent storage of settings and statistics
## Use Cases
### Primary Scenarios
- **Power Outage Detection** - Immediate alerts when systems restart unexpectedly
- **Windows Update Monitoring** - Track when systems reboot for updates
- **System Health Tracking** - Monitor restart frequency and patterns
- **Remote System Awareness** - Know when remote machines come online/offline
### Advanced Features
- **Reason Classification** - Distinguishes between planned and unplanned reboots
- **Uptime Tracking** - Reports system availability metrics
- **Historical Logging** - Maintains local logs for troubleshooting
- **Configuration Persistence** - Settings survive reboots and updates
## Installation Requirements
### Prerequisites
- Windows 10/11 or Windows Server
- PowerShell 5.1 or later
- Administrator privileges for Task Scheduler setup
- Network connectivity to Discord
- Discord webhook URL
### Dependencies
- Windows Event Log service
- Task Scheduler service
- PowerShell execution policy allowing script execution
## Security Considerations
- Scripts run with SYSTEM privileges for reliable event monitoring
- Webhook URLs stored as environment variables (not in scripts)
- No sensitive system information transmitted in notifications
- Local logging for audit trail
- Execution policy restrictions honored
## Integration Points
### Discord Integration
- Rich embedded messages with color-coded alerts
- Structured data format for easy parsing
- Error handling for network failures
- Retry logic for temporary connectivity issues
### Windows System Integration
- Event Log monitoring (IDs 1074, 6008, boot events)
- Task Scheduler automation
- WMI queries for system information
- Registry access for configuration persistence
## Troubleshooting
Common issues and solutions documented in setup instructions:
- PowerShell execution policy problems
- Network connectivity issues
- Task Scheduler permission errors
- Discord webhook validation failures
## Monitoring Capabilities
### Event Detection
- **Startup Events**: Boot completion, login ready state
- **Shutdown Events**: Planned shutdown initiation
- **Crash Recovery**: Unexpected shutdown detection
- **Update Reboots**: Windows Update initiated restarts
### Data Collection
- **System Metrics**: Uptime, boot time, restart counts
- **Event Correlation**: Links shutdown/startup events
- **Reason Analysis**: Determines root cause of reboots
- **Trend Tracking**: Historical restart patterns
## Deployment Strategy
1. **Single Machine**: Direct installation following setup guide
2. **Multiple Machines**: Script deployment via Group Policy or management tools
3. **Enterprise**: Integration with existing monitoring infrastructure
4. **Home Lab**: Centralized Discord channel for all systems
This monitoring system provides reliable Windows desktop/workstation oversight with minimal resource impact and maximum visibility into system events.

View File

@ -0,0 +1,205 @@
# Windows Reboot Monitor with Discord Notifications
# This script sends Discord webhook notifications when the system starts up or shuts down
param(
[Parameter(Mandatory=$true)]
[ValidateSet("startup", "shutdown")]
[string]$EventType,
[Parameter(Mandatory=$false)]
[string]$WebhookUrl = $env:DISCORD_WEBHOOK_URL,
[Parameter(Mandatory=$false)]
[string]$ComputerName = $env:COMPUTERNAME
)
# Configuration
$LogFile = "C:\Windows\Temp\reboot-monitor.log"
$ConfigFile = "C:\Windows\Temp\reboot-monitor-config.json"
# Function to log messages
function Write-Log {
param([string]$Message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp - $Message" | Out-File -Append -FilePath $LogFile
Write-Host "$timestamp - $Message"
}
# Function to load configuration
function Get-Configuration {
if (Test-Path $ConfigFile) {
try {
$config = Get-Content $ConfigFile | ConvertFrom-Json
return $config
} catch {
Write-Log "Error reading config file: $($_.Exception.Message)"
}
}
return $null
}
# Function to save configuration
function Save-Configuration {
param($config)
try {
$config | ConvertTo-Json | Out-File -FilePath $ConfigFile
Write-Log "Configuration saved to $ConfigFile"
} catch {
Write-Log "Error saving config: $($_.Exception.Message)"
}
}
# Function to send Discord notification
function Send-DiscordNotification {
param(
[string]$WebhookUrl,
[string]$Message,
[string]$Color = "3066993" # Default blue color
)
if ([string]::IsNullOrEmpty($WebhookUrl)) {
Write-Log "No Discord webhook URL provided"
return $false
}
$embed = @{
title = "Windows System Monitor"
description = $Message
color = [int]$Color
timestamp = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
fields = @(
@{
name = "Computer"
value = $ComputerName
inline = $true
},
@{
name = "Time"
value = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
inline = $true
}
)
}
$payload = @{
embeds = @($embed)
} | ConvertTo-Json -Depth 3
try {
$response = Invoke-RestMethod -Uri $WebhookUrl -Method Post -Body $payload -ContentType "application/json"
Write-Log "Discord notification sent successfully"
return $true
} catch {
Write-Log "Failed to send Discord notification: $($_.Exception.Message)"
return $false
}
}
# Function to get system uptime
function Get-SystemUptime {
$uptime = (Get-CimInstance -ClassName Win32_OperatingSystem).LastBootUpTime
$uptimeDuration = (Get-Date) - $uptime
return @{
LastBoot = $uptime.ToString("yyyy-MM-dd HH:mm:ss")
Uptime = "{0} days, {1} hours, {2} minutes" -f $uptimeDuration.Days, $uptimeDuration.Hours, $uptimeDuration.Minutes
}
}
# Function to detect reboot reason
function Get-RebootReason {
try {
$shutdownEvent = Get-WinEvent -FilterHashtable @{LogName='System'; ID=1074} -MaxEvents 1 -ErrorAction SilentlyContinue
if ($shutdownEvent) {
$message = $shutdownEvent.Message
if ($message -match "Windows Update") {
return "Windows Update"
} elseif ($message -match "power") {
return "Power related"
} elseif ($message -match "user") {
return "User initiated"
}
}
# Check for unexpected shutdowns
$unexpectedEvent = Get-WinEvent -FilterHashtable @{LogName='System'; ID=6008} -MaxEvents 1 -ErrorAction SilentlyContinue
if ($unexpectedEvent) {
return "Unexpected shutdown (possible power loss)"
}
return "Unknown reason"
} catch {
Write-Log "Error getting reboot reason: $($_.Exception.Message)"
return "Unable to determine"
}
}
# Main script logic
Write-Log "Windows Reboot Monitor started - Event: $EventType"
# Load configuration
$config = Get-Configuration
if (-not $config) {
$config = @{
LastStartup = $null
LastShutdown = $null
StartupCount = 0
WebhookUrl = $WebhookUrl
}
}
# Use webhook from config if not provided as parameter
if ([string]::IsNullOrEmpty($WebhookUrl) -and $config.WebhookUrl) {
$WebhookUrl = $config.WebhookUrl
}
# Update webhook URL in config if provided
if (-not [string]::IsNullOrEmpty($WebhookUrl)) {
$config.WebhookUrl = $WebhookUrl
}
switch ($EventType) {
"startup" {
Write-Log "System startup detected"
$config.StartupCount++
$config.LastStartup = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
# Get system information
$uptimeInfo = Get-SystemUptime()
$rebootReason = Get-RebootReason()
# Check if this is after an unexpected shutdown
$wasUnexpected = $false
if ($config.LastShutdown -eq $null -or $rebootReason -match "Unexpected|power") {
$wasUnexpected = $true
}
$message = if ($wasUnexpected) {
"🔴 **UNEXPECTED REBOOT DETECTED**`n`nSystem has restarted after an unexpected shutdown.`n`n**Possible cause:** $rebootReason`n**Boot time:** $($uptimeInfo.LastBoot)"
} else {
"🟢 **System Started**`n`nWindows machine is now online.`n`n**Reason:** $rebootReason`n**Boot time:** $($uptimeInfo.LastBoot)`n**Startup #:** $($config.StartupCount)"
}
$color = if ($wasUnexpected) { "15158332" } else { "3066993" } # Red for unexpected, blue for normal
Send-DiscordNotification -WebhookUrl $WebhookUrl -Message $message -Color $color
}
"shutdown" {
Write-Log "System shutdown detected"
$config.LastShutdown = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$uptimeInfo = Get-SystemUptime()
$rebootReason = Get-RebootReason()
$message = "🟡 **System Shutting Down**`n`nWindows machine is going offline.`n`n**Reason:** $rebootReason`n**Uptime:** $($uptimeInfo.Uptime)"
Send-DiscordNotification -WebhookUrl $WebhookUrl -Message $message -Color "16776960" # Yellow
}
}
# Save updated configuration
Save-Configuration -config $config
Write-Log "Windows Reboot Monitor completed - Event: $EventType"

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2024-01-01T00:00:00</Date>
<Author>System Administrator</Author>
<Description>Monitor system shutdown and send Discord notification</Description>
</RegistrationInfo>
<Triggers>
<SessionStateChangeTrigger>
<Enabled>true</Enabled>
<StateChange>SessionLock</StateChange>
</SessionStateChangeTrigger>
<EventTrigger>
<Enabled>true</Enabled>
<Subscription>&lt;QueryList&gt;&lt;Query Id="0" Path="System"&gt;&lt;Select Path="System"&gt;*[System[Provider[@Name='User32'] and EventID=1074]]&lt;/Select&gt;&lt;/Query&gt;&lt;/QueryList&gt;</Subscription>
</EventTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>S-1-5-18</UserId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT2M</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>powershell.exe</Command>
<Arguments>-ExecutionPolicy Bypass -File "C:\Scripts\windows-reboot-monitor.ps1" -EventType "shutdown"</Arguments>
</Exec>
</Actions>
</Task>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2024-01-01T00:00:00</Date>
<Author>System Administrator</Author>
<Description>Monitor system startup and send Discord notification</Description>
</RegistrationInfo>
<Triggers>
<BootTrigger>
<Enabled>true</Enabled>
<Delay>PT2M</Delay>
</BootTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>S-1-5-18</UserId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT5M</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>powershell.exe</Command>
<Arguments>-ExecutionPolicy Bypass -File "C:\Scripts\windows-reboot-monitor.ps1" -EventType "startup"</Arguments>
</Exec>
</Actions>
</Task>

View File

@ -0,0 +1,136 @@
# Windows Reboot Monitor Setup Instructions
This guide will help you set up Discord notifications for Windows reboots due to updates, power outages, or other events.
## Prerequisites
1. **Discord Webhook URL**: Create a webhook in your Discord server
- Go to Server Settings → Integrations → Webhooks
- Create a new webhook and copy the URL
2. **Administrator Access**: Required to set up scheduled tasks
## Installation Steps
### Step 1: Create Scripts Directory
```powershell
# Run as Administrator
New-Item -ItemType Directory -Path "C:\Scripts" -Force
```
### Step 2: Copy PowerShell Script
1. Copy `windows-reboot-monitor.ps1` to `C:\Scripts\`
2. Set execution policy (if needed):
```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
```
### Step 3: Configure Discord Webhook
Option A - Environment Variable (Recommended):
```powershell
# Set system environment variable
[Environment]::SetEnvironmentVariable("DISCORD_WEBHOOK_URL", "YOUR_WEBHOOK_URL_HERE", "Machine")
```
Option B - Direct parameter:
- Edit the Task Scheduler XML files to include your webhook URL in the arguments
### Step 4: Import Scheduled Tasks
```powershell
# Import startup monitoring task
schtasks /create /xml "C:\path\to\windows-reboot-task-startup.xml" /tn "Discord Reboot Monitor - Startup"
# Import shutdown monitoring task
schtasks /create /xml "C:\path\to\windows-reboot-task-shutdown.xml" /tn "Discord Reboot Monitor - Shutdown"
```
### Step 5: Test the Setup
```powershell
# Test startup notification
C:\Scripts\windows-reboot-monitor.ps1 -EventType "startup"
# Test shutdown notification
C:\Scripts\windows-reboot-monitor.ps1 -EventType "shutdown"
```
## What You'll Get
### Startup Notifications (Green/Red)
- **Green**: Normal startup with boot reason and uptime info
- **Red**: Unexpected restart (power loss, crash, etc.)
### Shutdown Notifications (Yellow)
- System going offline with uptime and shutdown reason
### Information Included
- Computer name
- Timestamp
- Boot/shutdown reason (Windows Update, power loss, user initiated)
- System uptime
- Startup counter
## Troubleshooting
### Check Logs
View logs at: `C:\Windows\Temp\reboot-monitor.log`
### Verify Tasks are Running
```powershell
# List scheduled tasks
Get-ScheduledTask | Where-Object {$_.TaskName -like "*Discord Reboot*"}
# Check task history
Get-WinEvent -LogName "Microsoft-Windows-TaskScheduler/Operational" | Where-Object {$_.LevelDisplayName -eq "Error"}
```
### Test Discord Webhook
```powershell
# Manual test
$webhook = "YOUR_WEBHOOK_URL"
$payload = @{content = "Test message from Windows"} | ConvertTo-Json
Invoke-RestMethod -Uri $webhook -Method Post -Body $payload -ContentType "application/json"
```
### Common Issues
1. **PowerShell Execution Policy**: Run `Set-ExecutionPolicy RemoteSigned`
2. **Network Issues**: Ensure Windows can reach Discord (discord.com)
3. **Permissions**: Run PowerShell as Administrator for setup
4. **Webhook URL**: Verify the Discord webhook URL is correct
### Event Log Monitoring
The script monitors these Windows events:
- **Event ID 1074**: System shutdown/restart
- **Event ID 6008**: Unexpected shutdown
- **Boot events**: System startup
## Security Notes
- Script runs with SYSTEM privileges for reliable monitoring
- Webhook URL is stored securely in environment variables or config
- Logs are stored in Windows temp directory
- No sensitive system information is transmitted
## Customization
Edit `windows-reboot-monitor.ps1` to:
- Change Discord message format
- Add additional system information
- Modify notification colors
- Adjust logging behavior
- Add email notifications as backup
## Uninstallation
```powershell
# Remove scheduled tasks
schtasks /delete /tn "Discord Reboot Monitor - Startup" /f
schtasks /delete /tn "Discord Reboot Monitor - Shutdown" /f
# Remove files
Remove-Item -Path "C:\Scripts\windows-reboot-monitor.ps1" -Force
Remove-Item -Path "C:\Windows\Temp\reboot-monitor.*" -Force
# Remove environment variable
[Environment]::SetEnvironmentVariable("DISCORD_WEBHOOK_URL", $null, "Machine")
```