Public/Send-SignalPushover.ps1
|
# PSGuerrilla - Jim Tyler, Microsoft MVP - CC BY 4.0 # https://github.com/jimrtyler/PSGuerrilla | https://creativecommons.org/licenses/by/4.0/ # AI/LLM use: see AI-USAGE.md for required attribution function Send-SignalPushover { <# .SYNOPSIS Sends a push notification via Pushover.net. .DESCRIPTION Delivers alert notifications to Pushover mobile/desktop apps using the Pushover Message API. Supports priority levels mapped from PSGuerrilla threat levels, with optional sound and URL parameters. .PARAMETER ApiToken Pushover application API token. .PARAMETER UserKey Pushover user key (or group key for team delivery). .PARAMETER Message The notification body text (max 1024 characters). .PARAMETER Title Optional notification title. .PARAMETER Priority Pushover priority: -2 (silent), -1 (quiet), 0 (normal), 1 (high), 2 (emergency). Emergency (2) requires Retry and Expire parameters. .PARAMETER Sound Notification sound name. Default: 'siren' for security alerts. .PARAMETER Url Optional URL to include in the notification. .PARAMETER UrlTitle Display text for the optional URL. .PARAMETER Retry Required when Priority=2. Seconds between retries (minimum 30). .PARAMETER Expire Required when Priority=2. Seconds before notification stops retrying (max 10800). .EXAMPLE Send-SignalPushover -ApiToken $token -UserKey $user -Message '3 CRITICAL threats detected' -Title 'PSGuerrilla Alert' -Priority 1 #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$ApiToken, [Parameter(Mandatory)] [string]$UserKey, [Parameter(Mandatory)] [string]$Message, [string]$Title = 'PSGuerrilla Signal', [ValidateRange(-2, 2)] [int]$Priority = 0, [string]$Sound = 'siren', [string]$Url, [string]$UrlTitle, [int]$Retry = 60, [int]$Expire = 3600 ) $uri = 'https://api.pushover.net/1/messages.json' # Truncate message to Pushover's 1024-char limit if ($Message.Length -gt 1024) { $Message = $Message.Substring(0, 1021) + '...' } $form = @{ token = $ApiToken user = $UserKey message = $Message title = $Title priority = $Priority sound = $Sound html = 1 } if ($Url) { $form['url'] = $Url } if ($UrlTitle) { $form['url_title'] = $UrlTitle } # Emergency priority requires retry/expire if ($Priority -eq 2) { $form['retry'] = [Math]::Max(30, $Retry) $form['expire'] = [Math]::Min(10800, $Expire) } try { $response = Invoke-RestMethod -Uri $uri -Method Post -Body $form -ErrorAction Stop if ($response.status -eq 1) { return [PSCustomObject]@{ Provider = 'Pushover' Success = $true Message = "Push notification sent (request: $($response.request))" Error = $null } } else { return [PSCustomObject]@{ Provider = 'Pushover' Success = $false Message = 'Pushover returned non-success status' Error = ($response.errors -join '; ') } } } catch { Start-Sleep -Seconds 3 try { $response = Invoke-RestMethod -Uri $uri -Method Post -Body $form -ErrorAction Stop if ($response.status -eq 1) { return [PSCustomObject]@{ Provider = 'Pushover' Success = $true Message = "Push notification sent on retry (request: $($response.request))" Error = $null } } else { return [PSCustomObject]@{ Provider = 'Pushover' Success = $false Message = 'Pushover returned non-success status on retry' Error = ($response.errors -join '; ') } } } catch { return [PSCustomObject]@{ Provider = 'Pushover' Success = $false Message = 'Failed to send push notification' Error = $_.Exception.Message } } } } |