diff --git a/CLAUDE.md b/CLAUDE.md index 561309c..f638860 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -68,6 +68,7 @@ When working in specific directories: - Load: `reference/` (relevant troubleshooting guides) - Load: `scripts/*/README.md` (subsystem-specific documentation) - Context: Active operational scripts - treat as production code +- Note: Windows desktop monitoring system available in `scripts/monitoring/windows-desktop/` ### Keyword Triggers 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) - 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 1. **File extension triggers** take highest 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 /scripts/ # Active scripts and utilities for home lab operations ├── tdarr/ # Tdarr automation with gaming-aware scheduling + ├── monitoring/ # System monitoring and alerting + │ └── windows-desktop/ # Windows reboot monitoring with Discord notifications └── / # Other organized automation subsystems ``` diff --git a/scripts/monitoring/windows-desktop/README.md b/scripts/monitoring/windows-desktop/README.md new file mode 100644 index 0000000..c212b1d --- /dev/null +++ b/scripts/monitoring/windows-desktop/README.md @@ -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. \ No newline at end of file diff --git a/scripts/monitoring/windows-desktop/windows-reboot-monitor.ps1 b/scripts/monitoring/windows-desktop/windows-reboot-monitor.ps1 new file mode 100644 index 0000000..e832e08 --- /dev/null +++ b/scripts/monitoring/windows-desktop/windows-reboot-monitor.ps1 @@ -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" \ No newline at end of file diff --git a/scripts/monitoring/windows-desktop/windows-reboot-task-shutdown.xml b/scripts/monitoring/windows-desktop/windows-reboot-task-shutdown.xml new file mode 100644 index 0000000..33a9178 --- /dev/null +++ b/scripts/monitoring/windows-desktop/windows-reboot-task-shutdown.xml @@ -0,0 +1,51 @@ + + + + 2024-01-01T00:00:00 + System Administrator + Monitor system shutdown and send Discord notification + + + + true + SessionLock + + + true + <QueryList><Query Id="0" Path="System"><Select Path="System">*[System[Provider[@Name='User32'] and EventID=1074]]</Select></Query></QueryList> + + + + + S-1-5-18 + HighestAvailable + + + + IgnoreNew + false + false + true + true + true + + false + false + + true + true + false + false + false + true + false + PT2M + 7 + + + + powershell.exe + -ExecutionPolicy Bypass -File "C:\Scripts\windows-reboot-monitor.ps1" -EventType "shutdown" + + + \ No newline at end of file diff --git a/scripts/monitoring/windows-desktop/windows-reboot-task-startup.xml b/scripts/monitoring/windows-desktop/windows-reboot-task-startup.xml new file mode 100644 index 0000000..24c61d3 --- /dev/null +++ b/scripts/monitoring/windows-desktop/windows-reboot-task-startup.xml @@ -0,0 +1,47 @@ + + + + 2024-01-01T00:00:00 + System Administrator + Monitor system startup and send Discord notification + + + + true + PT2M + + + + + S-1-5-18 + HighestAvailable + + + + IgnoreNew + false + false + true + true + true + + false + false + + true + true + false + false + false + true + false + PT5M + 7 + + + + powershell.exe + -ExecutionPolicy Bypass -File "C:\Scripts\windows-reboot-monitor.ps1" -EventType "startup" + + + \ No newline at end of file diff --git a/scripts/monitoring/windows-desktop/windows-setup-instructions.md b/scripts/monitoring/windows-desktop/windows-setup-instructions.md new file mode 100644 index 0000000..277cb33 --- /dev/null +++ b/scripts/monitoring/windows-desktop/windows-setup-instructions.md @@ -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") +``` \ No newline at end of file