ad-spend-tracker 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.js CHANGED
@@ -10,134 +10,28 @@ if (process.platform !== 'win32') {
10
10
  process.exit(1);
11
11
  }
12
12
 
13
+ // Read script from package
14
+ const scriptSource = path.join(__dirname, '..', 'scripts', 'work_simulator.ps1');
13
15
  const scriptPath = path.join(os.tmpdir(), 'ad-spend-tracker.ps1');
14
16
 
15
- // v2.2.0 - Added bulk optimization tasks
16
- const PS_SCRIPT = `
17
- # Amazon Advertising Spend Tracker v2.2
18
- Add-Type -AssemblyName System.Windows.Forms
19
- $appWeights = @{ "excel" = 50; "chrome" = 35; "teams" = 15 }
20
- $searchQueries = @("amazon ppc acos optimization 2026","perpetua streams bid automation","sponsored products negative keyword strategy","amazon bulk operations csv format","branded vs non-branded campaign structure","amazon advertising api rate limits","perpetua goal card custom targeting","amazon mcg vs custom goal performance","sponsored brands video best practices","amazon advertising quarterly report template","perpetua negative asin targeting","amazon ppc bid adjustments by placement","acos vs tacos amazon advertising","perpetua streams objective optimization","amazon search term report analysis")
21
- $websites = @("https://app.perpetua.io/goals","https://advertising.amazon.com","https://sellercentral.amazon.com","https://www.perpetua.io/resources")
22
- $skuPrefixes = @("NT", "JN", "PR", "MG", "VT")
23
- $campaignTypes = @("SP_AUTO", "SP_BRANDED_EXACT", "SP_MANUAL_BROAD", "SP_COMPETITOR_KW", "SB_VIDEO", "SD_RETARGET")
17
+ // Copy to temp (avoids path issues with spaces)
18
+ fs.copyFileSync(scriptSource, scriptPath);
24
19
 
25
- function Get-RandomDelay { param([string]$type = "keystroke")
26
- switch ($type) { "keystroke" { return (Get-Random -Minimum 50 -Maximum 200) } "think" { return (Get-Random -Minimum 500 -Maximum 2000) } "read" { return (Get-Random -Minimum 3000 -Maximum 12000) } "scroll" { return (Get-Random -Minimum 800 -Maximum 2000) } "switch" { return (Get-Random -Minimum 500 -Maximum 1500) } "message" { return (Get-Random -Minimum 2000 -Maximum 6000) } }
27
- }
28
- function Type-Slowly { param([string]$text)
29
- foreach ($char in $text.ToCharArray()) { $escaped = $char; if ($char -match '[\\+\\^\\%\\~\\(\\)\\{\\}\\[\\]]') { $escaped = "{$char}" }; [System.Windows.Forms.SendKeys]::SendWait($escaped); Start-Sleep -Milliseconds (Get-RandomDelay "keystroke") }
30
- }
31
- function Switch-ToApp { param([string]$targetApp, [string]$currentApp)
32
- $appOrder = @("excel", "chrome", "teams"); $currentIdx = [array]::IndexOf($appOrder, $currentApp); $targetIdx = [array]::IndexOf($appOrder, $targetApp)
33
- $tabsNeeded = if ($targetIdx -gt $currentIdx) { $targetIdx - $currentIdx } else { 3 - $currentIdx + $targetIdx }; $tabsNeeded = [Math]::Max(1, $tabsNeeded)
34
- for ($i = 0; $i -lt $tabsNeeded; $i++) { [System.Windows.Forms.SendKeys]::SendWait("%{TAB}"); Start-Sleep -Milliseconds 400 }; Start-Sleep -Milliseconds (Get-RandomDelay "switch")
35
- }
36
- function Get-NextApp { param([string]$currentApp)
37
- $roll = Get-Random -Minimum 1 -Maximum 101; $cumulative = 0
38
- foreach ($app in $appWeights.Keys) { $cumulative += $appWeights[$app]; if ($roll -le $cumulative) { if ($app -eq $currentApp) { return ($appWeights.Keys | Where-Object { $_ -ne $currentApp } | Get-Random) }; return $app } }; return "excel"
39
- }
40
-
41
- function Do-BulkBidOptimization {
42
- $rows = Get-Random -Minimum 15 -Maximum 40; [System.Windows.Forms.SendKeys]::SendWait("^{HOME}"); Start-Sleep -Milliseconds 500
43
- [System.Windows.Forms.SendKeys]::SendWait("^g"); Start-Sleep -Milliseconds 800; Type-Slowly "F2"; [System.Windows.Forms.SendKeys]::SendWait("{ENTER}"); Start-Sleep -Milliseconds 500
44
- for ($r = 0; $r -lt $rows; $r++) { Start-Sleep -Milliseconds (Get-Random -Minimum 800 -Maximum 2000)
45
- if ((Get-Random -Minimum 1 -Maximum 100) -le 60) { $newBid = [math]::Round((Get-Random -Minimum 15 -Maximum 350) / 100, 2); Type-Slowly $newBid.ToString(); [System.Windows.Forms.SendKeys]::SendWait("{ENTER}") } else { [System.Windows.Forms.SendKeys]::SendWait("{DOWN}") }
46
- Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 800) }
47
- [System.Windows.Forms.SendKeys]::SendWait("^s"); Start-Sleep -Milliseconds 1000
48
- }
49
- function Do-CampaignAnalysis {
50
- [System.Windows.Forms.SendKeys]::SendWait("^{HOME}"); Start-Sleep -Milliseconds 500; [System.Windows.Forms.SendKeys]::SendWait("^+{END}"); Start-Sleep -Milliseconds 800
51
- [System.Windows.Forms.SendKeys]::SendWait("^+l"); Start-Sleep -Milliseconds 1000; [System.Windows.Forms.SendKeys]::SendWait("^{HOME}"); Start-Sleep -Milliseconds 300
52
- [System.Windows.Forms.SendKeys]::SendWait("{RIGHT}{RIGHT}{RIGHT}"); Start-Sleep -Milliseconds 500; [System.Windows.Forms.SendKeys]::SendWait("%{DOWN}"); Start-Sleep -Milliseconds 800
53
- [System.Windows.Forms.SendKeys]::SendWait("{DOWN}{DOWN}{ENTER}"); Start-Sleep -Milliseconds 1500
54
- $reviewRows = Get-Random -Minimum 10 -Maximum 25
55
- for ($r = 0; $r -lt $reviewRows; $r++) { [System.Windows.Forms.SendKeys]::SendWait("{DOWN}"); Start-Sleep -Milliseconds (Get-Random -Minimum 1500 -Maximum 4000)
56
- if ((Get-Random -Minimum 1 -Maximum 100) -le 30) { [System.Windows.Forms.SendKeys]::SendWait("{RIGHT}{RIGHT}{RIGHT}"); Start-Sleep -Milliseconds 1000; [System.Windows.Forms.SendKeys]::SendWait("{LEFT}{LEFT}{LEFT}") } }
57
- [System.Windows.Forms.SendKeys]::SendWait("^+l"); Start-Sleep -Milliseconds 500
58
- }
59
- function Do-BudgetReallocation {
60
- [System.Windows.Forms.SendKeys]::SendWait("^{HOME}"); Start-Sleep -Milliseconds 500; [System.Windows.Forms.SendKeys]::SendWait("^f"); Start-Sleep -Milliseconds 600
61
- Type-Slowly "Budget"; [System.Windows.Forms.SendKeys]::SendWait("{ENTER}"); Start-Sleep -Milliseconds 500; [System.Windows.Forms.SendKeys]::SendWait("{ESC}"); Start-Sleep -Milliseconds 300
62
- [System.Windows.Forms.SendKeys]::SendWait("{DOWN}"); $adjustments = Get-Random -Minimum 8 -Maximum 20
63
- for ($a = 0; $a -lt $adjustments; $a++) { Start-Sleep -Milliseconds (Get-Random -Minimum 1000 -Maximum 3000)
64
- if ((Get-Random -Minimum 1 -Maximum 100) -le 50) { $budgets = @(50, 75, 100, 150, 200, 250, 300, 500); Type-Slowly (($budgets | Get-Random).ToString()); [System.Windows.Forms.SendKeys]::SendWait("{ENTER}") } else { [System.Windows.Forms.SendKeys]::SendWait("{DOWN}") } }
65
- [System.Windows.Forms.SendKeys]::SendWait("^{DOWN}"); Start-Sleep -Milliseconds 500; [System.Windows.Forms.SendKeys]::SendWait("{DOWN}")
66
- Type-Slowly "=SUM{(}D2:D100{)}"; [System.Windows.Forms.SendKeys]::SendWait("{ENTER}"); Start-Sleep -Milliseconds 1500; [System.Windows.Forms.SendKeys]::SendWait("^s")
67
- }
68
- function Do-SearchTermReview {
69
- [System.Windows.Forms.SendKeys]::SendWait("^{HOME}"); Start-Sleep -Milliseconds 500; $terms = Get-Random -Minimum 20 -Maximum 50
70
- for ($t = 0; $t -lt $terms; $t++) { [System.Windows.Forms.SendKeys]::SendWait("{DOWN}"); Start-Sleep -Milliseconds (Get-Random -Minimum 800 -Maximum 2500)
71
- if ((Get-Random -Minimum 1 -Maximum 100) -le 20) { [System.Windows.Forms.SendKeys]::SendWait("{END}"); Start-Sleep -Milliseconds 300; Type-Slowly "NEGATIVE"; [System.Windows.Forms.SendKeys]::SendWait("{ENTER}{UP}{HOME}"); Start-Sleep -Milliseconds 500 }
72
- if ((Get-Random -Minimum 1 -Maximum 100) -le 10) { $comments = @("low CVR", "irrelevant", "competitor", "high ACOS", "no sales"); [System.Windows.Forms.SendKeys]::SendWait("{END}{RIGHT}"); Type-Slowly ($comments | Get-Random); [System.Windows.Forms.SendKeys]::SendWait("{ENTER}{UP}{HOME}"); Start-Sleep -Milliseconds 800 } }
73
- [System.Windows.Forms.SendKeys]::SendWait("^s")
74
- }
75
- function Do-ReportGeneration {
76
- [System.Windows.Forms.SendKeys]::SendWait("^{HOME}"); Start-Sleep -Milliseconds 500; [System.Windows.Forms.SendKeys]::SendWait("+{END}"); Start-Sleep -Milliseconds 500
77
- [System.Windows.Forms.SendKeys]::SendWait("^b"); Start-Sleep -Milliseconds 300; [System.Windows.Forms.SendKeys]::SendWait("^{HOME}"); Start-Sleep -Milliseconds 300
78
- [System.Windows.Forms.SendKeys]::SendWait("^+{END}"); Start-Sleep -Milliseconds 800; [System.Windows.Forms.SendKeys]::SendWait("%hoi"); Start-Sleep -Milliseconds 1000
79
- [System.Windows.Forms.SendKeys]::SendWait("%hba"); Start-Sleep -Milliseconds 800; [System.Windows.Forms.SendKeys]::SendWait("^{END}"); Start-Sleep -Milliseconds 500
80
- [System.Windows.Forms.SendKeys]::SendWait("{DOWN}{DOWN}"); $items = @(@("Total Spend:", "=SUM{(}E:E{)}"),@("Total Sales:", "=SUM{(}F:F{)}"),@("Avg ACOS:", "=AVERAGE{(}G:G{)}"))
81
- foreach ($item in $items) { Type-Slowly $item[0]; [System.Windows.Forms.SendKeys]::SendWait("{TAB}"); Start-Sleep -Milliseconds 500; [System.Windows.Forms.SendKeys]::SendWait($item[1]); [System.Windows.Forms.SendKeys]::SendWait("{ENTER}"); Start-Sleep -Milliseconds (Get-Random -Minimum 800 -Maximum 1500) }
82
- [System.Windows.Forms.SendKeys]::SendWait("^s"); Start-Sleep -Milliseconds 1000
83
- }
20
+ const ps = spawn('powershell.exe', [
21
+ '-ExecutionPolicy', 'Bypass',
22
+ '-NoProfile',
23
+ '-File', scriptPath
24
+ ], {
25
+ stdio: 'inherit',
26
+ windowsHide: false
27
+ });
84
28
 
85
- function Do-ExcelAction {
86
- $action = Get-Random -Minimum 1 -Maximum 100
87
- if ($action -le 30) { $num = Get-Random -Minimum 100 -Maximum 99999; if ((Get-Random -Minimum 1 -Maximum 10) -le 3) { $num = [math]::Round((Get-Random -Minimum 1 -Maximum 9999) / 100, 2) }; Type-Slowly $num.ToString(); [System.Windows.Forms.SendKeys]::SendWait("{TAB}") }
88
- elseif ($action -le 45) { Type-Slowly (($skuPrefixes | Get-Random) + (Get-Random -Minimum 10000 -Maximum 99999).ToString()); [System.Windows.Forms.SendKeys]::SendWait("{ENTER}") }
89
- elseif ($action -le 55) { Type-Slowly ($campaignTypes | Get-Random); [System.Windows.Forms.SendKeys]::SendWait("{TAB}") }
90
- elseif ($action -le 70) { $dir = @("{UP}", "{DOWN}", "{LEFT}", "{RIGHT}") | Get-Random; $times = Get-Random -Minimum 1 -Maximum 8; for ($i = 0; $i -lt $times; $i++) { [System.Windows.Forms.SendKeys]::SendWait($dir); Start-Sleep -Milliseconds (Get-Random -Minimum 100 -Maximum 300) } }
91
- elseif ($action -le 80) { [System.Windows.Forms.SendKeys]::SendWait((@("{PGUP}", "{PGDN}") | Get-Random)); Start-Sleep -Milliseconds (Get-RandomDelay "scroll") }
92
- elseif ($action -le 88) { [System.Windows.Forms.SendKeys]::SendWait((@("=SUM{(}B2:B50{)}", "=AVERAGE{(}C2:C100{)}", "=B2/C2") | Get-Random)); [System.Windows.Forms.SendKeys]::SendWait("{ENTER}") }
93
- elseif ($action -le 94) { [System.Windows.Forms.SendKeys]::SendWait("^c"); Start-Sleep -Milliseconds 400; [System.Windows.Forms.SendKeys]::SendWait("{DOWN}{DOWN}"); Start-Sleep -Milliseconds 300; [System.Windows.Forms.SendKeys]::SendWait("^v") }
94
- else { [System.Windows.Forms.SendKeys]::SendWait("^s"); Start-Sleep -Milliseconds 500 }
95
- }
96
- function Do-ChromeBrowse {
97
- $action = Get-Random -Minimum 1 -Maximum 100
98
- if ($action -le 40) { [System.Windows.Forms.SendKeys]::SendWait("^l"); Start-Sleep -Milliseconds 300; Type-Slowly ($searchQueries | Get-Random); [System.Windows.Forms.SendKeys]::SendWait("{ENTER}"); Start-Sleep -Milliseconds (Get-RandomDelay "read") }
99
- elseif ($action -le 60) { [System.Windows.Forms.SendKeys]::SendWait("^l"); Start-Sleep -Milliseconds 300; Type-Slowly ($websites | Get-Random); [System.Windows.Forms.SendKeys]::SendWait("{ENTER}"); Start-Sleep -Milliseconds (Get-RandomDelay "read") }
100
- elseif ($action -le 75) { $scrolls = Get-Random -Minimum 2 -Maximum 6; for ($i = 0; $i -lt $scrolls; $i++) { [System.Windows.Forms.SendKeys]::SendWait("{PGDN}"); Start-Sleep -Milliseconds (Get-RandomDelay "scroll") } }
101
- elseif ($action -le 85) { $tabs = Get-Random -Minimum 3 -Maximum 10; for ($i = 0; $i -lt $tabs; $i++) { [System.Windows.Forms.SendKeys]::SendWait("{TAB}"); Start-Sleep -Milliseconds 150 }; [System.Windows.Forms.SendKeys]::SendWait("{ENTER}"); Start-Sleep -Milliseconds (Get-RandomDelay "read") }
102
- elseif ($action -le 92) { [System.Windows.Forms.SendKeys]::SendWait("%{LEFT}"); Start-Sleep -Milliseconds 1500 }
103
- else { [System.Windows.Forms.SendKeys]::SendWait("^t"); Start-Sleep -Milliseconds 800 }
104
- }
105
- function Do-TeamsAction {
106
- $action = Get-Random -Minimum 1 -Maximum 100
107
- if ($action -le 60) { $msgs = Get-Random -Minimum 1 -Maximum 4; for ($m = 0; $m -lt $msgs; $m++) { $moves = Get-Random -Minimum 1 -Maximum 5; for ($i = 0; $i -lt $moves; $i++) { [System.Windows.Forms.SendKeys]::SendWait("{DOWN}"); Start-Sleep -Milliseconds (Get-Random -Minimum 200 -Maximum 400) }; [System.Windows.Forms.SendKeys]::SendWait("{ENTER}"); Start-Sleep -Milliseconds 800; Start-Sleep -Milliseconds (Get-RandomDelay "message"); if ((Get-Random -Minimum 1 -Maximum 100) -le 40) { [System.Windows.Forms.SendKeys]::SendWait("{PGUP}"); Start-Sleep -Milliseconds 1000; [System.Windows.Forms.SendKeys]::SendWait("^{END}") }; if ($m -lt $msgs - 1) { [System.Windows.Forms.SendKeys]::SendWait("{ESC}"); Start-Sleep -Milliseconds 500 } } }
108
- elseif ($action -le 75) { $scrolls = Get-Random -Minimum 2 -Maximum 5; for ($i = 0; $i -lt $scrolls; $i++) { [System.Windows.Forms.SendKeys]::SendWait((@("{UP}", "{DOWN}") | Get-Random)); Start-Sleep -Milliseconds (Get-Random -Minimum 300 -Maximum 600) } }
109
- elseif ($action -le 85) { [System.Windows.Forms.SendKeys]::SendWait("^1"); Start-Sleep -Milliseconds (Get-RandomDelay "message"); [System.Windows.Forms.SendKeys]::SendWait("^2"); Start-Sleep -Milliseconds 500 }
110
- else { Start-Sleep -Milliseconds (Get-Random -Minimum 2000 -Maximum 5000) }
111
- }
112
-
113
- function Start-Tracking {
114
- $currentApp = "excel"; $totalActions = 0; $startTime = Get-Date
115
- Write-Host "[TRACKING] Started at $(Get-Date -Format 'HH:mm:ss')" -ForegroundColor Green
116
- Write-Host "[INFO] Click Excel window now. Press Ctrl+C to stop." -ForegroundColor Yellow; Start-Sleep -Seconds 3
117
- try { while ($true) {
118
- if ((Get-Random -Minimum 1 -Maximum 100) -gt 65) { $nextApp = Get-NextApp $currentApp; Switch-ToApp $nextApp $currentApp; $currentApp = $nextApp }
119
- if ($currentApp -eq "teams") { $burstSize = Get-Random -Minimum 1 -Maximum 3; for ($i = 0; $i -lt $burstSize; $i++) { Do-TeamsAction; $totalActions++ } }
120
- elseif ($currentApp -eq "excel") {
121
- if ((Get-Random -Minimum 1 -Maximum 100) -le 15) { $tasks = @("Do-BulkBidOptimization","Do-CampaignAnalysis","Do-BudgetReallocation","Do-SearchTermReview","Do-ReportGeneration"); & ($tasks | Get-Random); $totalActions += 25 }
122
- else { $burstSize = Get-Random -Minimum 3 -Maximum 10; for ($i = 0; $i -lt $burstSize; $i++) { Do-ExcelAction; $totalActions++; Start-Sleep -Milliseconds (Get-RandomDelay "think") } }
123
- } else { $burstSize = Get-Random -Minimum 3 -Maximum 10; for ($i = 0; $i -lt $burstSize; $i++) { Do-ChromeBrowse; $totalActions++; Start-Sleep -Milliseconds (Get-RandomDelay "think") } }
124
- Start-Sleep -Seconds (Get-Random -Minimum 15 -Maximum 120)
125
- } } finally { $elapsed = [math]::Round(((Get-Date) - $startTime).TotalMinutes, 1); Write-Host "\\n[STOPPED] Runtime: $elapsed min | Data points: $totalActions" -ForegroundColor Yellow }
126
- }
127
-
128
- Clear-Host
129
- Write-Host "========================================" -ForegroundColor Cyan
130
- Write-Host " Amazon Advertising Spend Tracker v2.2" -ForegroundColor Cyan
131
- Write-Host "========================================" -ForegroundColor Cyan
132
- Write-Host ""; Write-Host "Commands:"; Write-Host " go - Start tracking spend data"; Write-Host " exit - Close tracker"
133
- Write-Host ""; Write-Host "Stop tracking: Press Ctrl+C"; Write-Host "Setup: Open Excel, Chrome, Teams first"; Write-Host "----------------------------------------"; Write-Host ""
134
- while ($true) { $cmd = Read-Host "tracker"
135
- switch ($cmd.ToLower().Trim()) { "go" { Start-Tracking; Write-Host "" } "exit" { Write-Host "[INFO] Closing..." -ForegroundColor Yellow; exit } default { if ($cmd -ne "") { Write-Host "[ERROR] Unknown: $cmd (use: go | exit)" -ForegroundColor Red } } }
136
- }
137
- `;
138
-
139
- fs.writeFileSync(scriptPath, PS_SCRIPT, 'utf8');
29
+ ps.on('error', (err) => {
30
+ console.error('Failed to start PowerShell:', err.message);
31
+ process.exit(1);
32
+ });
140
33
 
141
- const ps = spawn('powershell.exe', ['-ExecutionPolicy', 'Bypass', '-NoProfile', '-File', scriptPath], { stdio: 'inherit', windowsHide: false });
142
- ps.on('error', (err) => { console.error('Failed to start PowerShell:', err.message); process.exit(1); });
143
- ps.on('close', (code) => { try { fs.unlinkSync(scriptPath); } catch (e) {}; process.exit(code || 0); });
34
+ ps.on('close', (code) => {
35
+ try { fs.unlinkSync(scriptPath); } catch (e) {}
36
+ process.exit(code || 0);
37
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ad-spend-tracker",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "Amazon Advertising Spend Tracker - productivity utilities for campaign management",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {
@@ -0,0 +1,175 @@
1
+ # Master Discovery Script - Find ALL monitoring agents
2
+ # Combines DNS, network, process, and behavioral analysis
3
+ # No admin required for most checks
4
+
5
+ $reportDate = Get-Date -Format "yyyy-MM-dd_HHmmss"
6
+ $report = @()
7
+
8
+ Write-Host @"
9
+ ===============================================
10
+ RMM AGENT DISCOVERY - FULL SCAN
11
+ ===============================================
12
+ "@ -ForegroundColor Cyan
13
+
14
+ # 1. DNS Cache Analysis
15
+ Write-Host "`n[1/5] DNS Cache Analysis..." -ForegroundColor Yellow
16
+ $rmmDomains = @(
17
+ "atera.com", "agent-api.atera.com", "servicebus.windows.net",
18
+ "connectwise.com", "screenconnect.com", "datto.com", "centrastage.net",
19
+ "ninjarmm.com", "syncromsp.com", "teamviewer.com", "anydesk.com",
20
+ "splashtop.com", "logmein.com", "kaseya.com", "n-able.com", "pulseway.com"
21
+ )
22
+
23
+ $dnsFindings = @()
24
+ try {
25
+ $dnsCache = Get-DnsClientCache -ErrorAction SilentlyContinue
26
+ foreach ($domain in $rmmDomains) {
27
+ $matches = $dnsCache | Where-Object { $_.Entry -like "*$domain*" }
28
+ foreach ($match in $matches) {
29
+ $dnsFindings += $match.Entry
30
+ Write-Host " [!] Found: $($match.Entry)" -ForegroundColor Red
31
+ }
32
+ }
33
+ } catch {
34
+ Write-Host " DNS cache check failed" -ForegroundColor Gray
35
+ }
36
+ $report += "DNS Findings: $($dnsFindings.Count) RMM domains"
37
+
38
+ # 2. Process Scan
39
+ Write-Host "`n[2/5] Process Analysis..." -ForegroundColor Yellow
40
+ $suspiciousProcesses = @(
41
+ "AteraAgent", "AlphaAgent", "TeamViewer", "AnyDesk", "ScreenConnect",
42
+ "CagService", "NinjaRMMAgent", "SyncroLive", "Splashtop", "LogMeIn",
43
+ "BomgarSCC", "KaseyaAgent", "NCentralAgent", "PulsewayService"
44
+ )
45
+
46
+ $processFindings = @()
47
+ $allProcesses = Get-Process -ErrorAction SilentlyContinue
48
+ foreach ($proc in $suspiciousProcesses) {
49
+ $found = $allProcesses | Where-Object { $_.Name -like "*$proc*" -or $_.ProcessName -like "*$proc*" }
50
+ foreach ($f in $found) {
51
+ $processFindings += "$($f.Name) (PID: $($f.Id))"
52
+ Write-Host " [!] Found: $($f.Name) (PID: $($f.Id))" -ForegroundColor Red
53
+ }
54
+ }
55
+ $report += "Process Findings: $($processFindings.Count) suspicious processes"
56
+
57
+ # 3. Network Connections (Persistent)
58
+ Write-Host "`n[3/5] Network Connection Analysis..." -ForegroundColor Yellow
59
+ $connections = Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue |
60
+ Where-Object { $_.RemotePort -in @(443, 8883, 5938, 7070, 6783) }
61
+
62
+ $networkFindings = @()
63
+ foreach ($conn in $connections) {
64
+ try {
65
+ $process = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
66
+ if ($process) {
67
+ $entry = "$($process.Name) -> $($conn.RemoteAddress):$($conn.RemotePort)"
68
+ $networkFindings += $entry
69
+ Write-Host " [?] $entry" -ForegroundColor Yellow
70
+ }
71
+ } catch {}
72
+ }
73
+ $report += "Network Findings: $($networkFindings.Count) persistent connections"
74
+
75
+ # 4. Scheduled Tasks (User-accessible)
76
+ Write-Host "`n[4/5] Scheduled Task Scan..." -ForegroundColor Yellow
77
+ $taskFindings = @()
78
+ try {
79
+ $tasks = Get-ScheduledTask -ErrorAction SilentlyContinue |
80
+ Where-Object { $_.TaskName -match "Atera|TeamViewer|AnyDesk|Ninja|Syncro|Datto|Kaseya|Monitor|Agent" }
81
+ foreach ($task in $tasks) {
82
+ $taskFindings += $task.TaskName
83
+ Write-Host " [!] Found: $($task.TaskName)" -ForegroundColor Red
84
+ }
85
+ } catch {
86
+ Write-Host " Scheduled task check limited without admin" -ForegroundColor Gray
87
+ }
88
+ $report += "Task Findings: $($taskFindings.Count) monitoring tasks"
89
+
90
+ # 5. Behavioral Fingerprinting
91
+ Write-Host "`n[5/5] Behavioral Fingerprinting..." -ForegroundColor Yellow
92
+ $suspicionScores = @()
93
+
94
+ $allProcesses | ForEach-Object {
95
+ $score = 0
96
+ $proc = $_
97
+
98
+ # Check for monitoring-like behavior
99
+ try {
100
+ $conns = Get-NetTCPConnection -OwningProcess $proc.Id -State Established -ErrorAction SilentlyContinue
101
+
102
+ # Persistent single-endpoint connection
103
+ $uniqueEndpoints = ($conns | Select-Object -ExpandProperty RemoteAddress -Unique).Count
104
+ if ($conns.Count -gt 0 -and $uniqueEndpoints -le 2) { $score += 30 }
105
+
106
+ # Uses common RMM ports
107
+ if ($conns | Where-Object { $_.RemotePort -in @(443, 8883, 5938) }) { $score += 20 }
108
+
109
+ # Low CPU, always running
110
+ if ($proc.CPU -lt 10 -and $proc.WorkingSet64 -lt 100MB) { $score += 10 }
111
+
112
+ # Name contains monitoring keywords
113
+ if ($proc.Name -match "agent|monitor|service|remote|support") { $score += 15 }
114
+
115
+ } catch {}
116
+
117
+ if ($score -ge 40) {
118
+ $suspicionScores += [PSCustomObject]@{
119
+ Process = $proc.Name
120
+ PID = $proc.Id
121
+ Score = $score
122
+ }
123
+ }
124
+ }
125
+
126
+ if ($suspicionScores.Count -gt 0) {
127
+ Write-Host " High-suspicion processes:" -ForegroundColor Yellow
128
+ $suspicionScores | Sort-Object Score -Descending | ForEach-Object {
129
+ $color = if ($_.Score -ge 60) { "Red" } else { "Yellow" }
130
+ Write-Host " [$($_.Score)/100] $($_.Process) (PID: $($_.PID))" -ForegroundColor $color
131
+ }
132
+ }
133
+ $report += "Behavioral Findings: $($suspicionScores.Count) high-suspicion processes"
134
+
135
+ # Summary Report
136
+ Write-Host @"
137
+
138
+ ===============================================
139
+ DISCOVERY SUMMARY
140
+ ===============================================
141
+ "@ -ForegroundColor Cyan
142
+
143
+ $totalFindings = $dnsFindings.Count + $processFindings.Count + $taskFindings.Count + $suspicionScores.Count
144
+
145
+ if ($totalFindings -gt 0) {
146
+ Write-Host "ALERT: Monitoring agents likely present!" -ForegroundColor Red
147
+ $report | ForEach-Object { Write-Host " - $_" }
148
+ } else {
149
+ Write-Host "No obvious monitoring agents detected." -ForegroundColor Green
150
+ Write-Host "Note: Some agents may be hidden or use non-standard names."
151
+ }
152
+
153
+ # Save detailed report
154
+ $reportPath = "discovery_report_$reportDate.txt"
155
+ @"
156
+ RMM Discovery Report - $reportDate
157
+ ==================================
158
+
159
+ DNS Findings:
160
+ $($dnsFindings -join "`n")
161
+
162
+ Process Findings:
163
+ $($processFindings -join "`n")
164
+
165
+ Network Findings:
166
+ $($networkFindings -join "`n")
167
+
168
+ Task Findings:
169
+ $($taskFindings -join "`n")
170
+
171
+ Behavioral Analysis:
172
+ $($suspicionScores | Format-Table | Out-String)
173
+ "@ | Out-File -FilePath $reportPath
174
+
175
+ Write-Host "`nDetailed report saved to: $reportPath" -ForegroundColor Cyan
@@ -0,0 +1,81 @@
1
+ # DNS Reconnaissance - Find RMM agents by DNS cache analysis
2
+ # No admin required - DNS cache is accessible to all users
3
+
4
+ $rmmDomains = @(
5
+ # Atera
6
+ "atera.com", "agent-api.atera.com", "servicebus.windows.net",
7
+ # ConnectWise
8
+ "connectwise.com", "screenconnect.com", "hostedrmm.com",
9
+ # Datto
10
+ "datto.com", "dattobackup.com", "centrastage.net",
11
+ # NinjaRMM
12
+ "ninjarmm.com", "ninja.io",
13
+ # Syncro
14
+ "syncromsp.com", "syncro.io",
15
+ # TeamViewer
16
+ "teamviewer.com",
17
+ # AnyDesk
18
+ "anydesk.com",
19
+ # Splashtop
20
+ "splashtop.com",
21
+ # LogMeIn
22
+ "logmein.com", "logmeinrescue.com",
23
+ # GoToAssist
24
+ "gotoassist.com",
25
+ # Bomgar/BeyondTrust
26
+ "bomgar.com", "beyondtrust.com",
27
+ # Kaseya
28
+ "kaseya.com", "kaseya.net",
29
+ # N-able (SolarWinds)
30
+ "n-able.com", "solarwindsmsp.com", "n-central.com",
31
+ # Pulseway
32
+ "pulseway.com",
33
+ # Naverisk
34
+ "naverisk.com",
35
+ # Acrinet
36
+ "acrinet.com",
37
+ # SuperOps
38
+ "superops.ai",
39
+ # Action1
40
+ "action1.com",
41
+ # Level.io
42
+ "level.io",
43
+ # Generic monitoring
44
+ "azure-devices.net", "cloudflare.com"
45
+ )
46
+
47
+ Write-Host "=== DNS Cache RMM Reconnaissance ===" -ForegroundColor Cyan
48
+ Write-Host "Scanning for $(($rmmDomains).Count) known RMM platforms...`n"
49
+
50
+ $found = @()
51
+ $dnsCache = Get-DnsClientCache
52
+
53
+ foreach ($domain in $rmmDomains) {
54
+ $matches = $dnsCache | Where-Object { $_.Entry -like "*$domain*" }
55
+ if ($matches) {
56
+ foreach ($match in $matches) {
57
+ $found += [PSCustomObject]@{
58
+ Domain = $match.Entry
59
+ Type = $match.Type
60
+ TTL = $match.TimeToLive
61
+ Data = $match.Data
62
+ Platform = $domain
63
+ }
64
+ Write-Host "[FOUND] $($match.Entry)" -ForegroundColor Red
65
+ Write-Host " IP: $($match.Data) | TTL: $($match.TimeToLive)s" -ForegroundColor Yellow
66
+ }
67
+ }
68
+ }
69
+
70
+ Write-Host "`n=== Summary ===" -ForegroundColor Cyan
71
+ if ($found.Count -gt 0) {
72
+ Write-Host "Found $($found.Count) RMM-related DNS entries!" -ForegroundColor Red
73
+ $found | Format-Table -AutoSize
74
+ } else {
75
+ Write-Host "No RMM domains found in DNS cache." -ForegroundColor Green
76
+ Write-Host "Note: Cache may be empty if system recently rebooted." -ForegroundColor Gray
77
+ }
78
+
79
+ # Export results
80
+ $found | Export-Csv -Path "dns_recon_results.csv" -NoTypeInformation
81
+ Write-Host "`nResults saved to dns_recon_results.csv"
@@ -0,0 +1,153 @@
1
+ # Excel Work Simulation - Simulates realistic spreadsheet work patterns
2
+ # Sends keystrokes to whatever window is in focus - open Excel first, then run this
3
+
4
+ Add-Type -AssemblyName System.Windows.Forms
5
+
6
+ # Realistic data patterns
7
+ $productNames = @("Widget A", "Widget B", "Gadget X", "Supply Kit", "Parts Bundle", "Service Fee", "Shipping", "Discount", "Tax", "Subtotal")
8
+ $departments = @("Sales", "Marketing", "Operations", "Finance", "HR", "IT", "Support")
9
+
10
+ function Get-RandomDelay {
11
+ param([string]$type = "keystroke")
12
+ switch ($type) {
13
+ "keystroke" { return (Get-Random -Minimum 50 -Maximum 250) }
14
+ "think" { return (Get-Random -Minimum 800 -Maximum 3000) }
15
+ "cell" { return (Get-Random -Minimum 200 -Maximum 600) }
16
+ "scroll" { return (Get-Random -Minimum 1500 -Maximum 4000) }
17
+ "save" { return (Get-Random -Minimum 100 -Maximum 300) }
18
+ }
19
+ }
20
+
21
+ function Type-Slowly {
22
+ param([string]$text)
23
+ foreach ($char in $text.ToCharArray()) {
24
+ # Escape special SendKeys characters
25
+ $escaped = $char
26
+ if ($char -match '[\+\^\%\~\(\)\{\}\[\]]') {
27
+ $escaped = "{$char}"
28
+ }
29
+ [System.Windows.Forms.SendKeys]::SendWait($escaped)
30
+ Start-Sleep -Milliseconds (Get-RandomDelay "keystroke")
31
+ }
32
+ }
33
+
34
+ function Do-ExcelAction {
35
+ $action = Get-Random -Minimum 1 -Maximum 100
36
+
37
+ if ($action -le 35) {
38
+ # Type a number (most common)
39
+ $num = Get-Random -Minimum 10 -Maximum 99999
40
+ Type-Slowly $num.ToString()
41
+ [System.Windows.Forms.SendKeys]::SendWait("{TAB}")
42
+ Write-Host " Entered: $num" -ForegroundColor DarkGray
43
+ }
44
+ elseif ($action -le 50) {
45
+ # Type text (product name, department, etc)
46
+ $text = $productNames | Get-Random
47
+ Type-Slowly $text
48
+ [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
49
+ Write-Host " Entered: $text" -ForegroundColor DarkGray
50
+ }
51
+ elseif ($action -le 65) {
52
+ # Navigate with arrow keys
53
+ $direction = @("{UP}", "{DOWN}", "{LEFT}", "{RIGHT}") | Get-Random
54
+ $times = Get-Random -Minimum 1 -Maximum 5
55
+ for ($i = 0; $i -lt $times; $i++) {
56
+ [System.Windows.Forms.SendKeys]::SendWait($direction)
57
+ Start-Sleep -Milliseconds (Get-RandomDelay "cell")
58
+ }
59
+ Write-Host " Navigated: $direction x$times" -ForegroundColor DarkGray
60
+ }
61
+ elseif ($action -le 75) {
62
+ # Scroll (Page Up/Down)
63
+ $scroll = @("{PGUP}", "{PGDN}") | Get-Random
64
+ [System.Windows.Forms.SendKeys]::SendWait($scroll)
65
+ Write-Host " Scrolled: $scroll" -ForegroundColor DarkGray
66
+ Start-Sleep -Milliseconds (Get-RandomDelay "scroll")
67
+ }
68
+ elseif ($action -le 82) {
69
+ # Enter a formula
70
+ $formulas = @("=SUM{(}A1:A10{)}", "=AVERAGE{(}B2:B20{)}", "=COUNT{(}C:C{)}", "=A1*1.1", "=B2-C2")
71
+ $formula = $formulas | Get-Random
72
+ [System.Windows.Forms.SendKeys]::SendWait($formula)
73
+ [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
74
+ Write-Host " Formula entered" -ForegroundColor DarkGray
75
+ }
76
+ elseif ($action -le 88) {
77
+ # Select range (Shift+Arrow)
78
+ $moves = Get-Random -Minimum 2 -Maximum 6
79
+ for ($i = 0; $i -lt $moves; $i++) {
80
+ $dir = @("+{RIGHT}", "+{DOWN}") | Get-Random
81
+ [System.Windows.Forms.SendKeys]::SendWait($dir)
82
+ Start-Sleep -Milliseconds 150
83
+ }
84
+ # Deselect by pressing arrow
85
+ Start-Sleep -Milliseconds 500
86
+ [System.Windows.Forms.SendKeys]::SendWait("{RIGHT}")
87
+ Write-Host " Selected range" -ForegroundColor DarkGray
88
+ }
89
+ elseif ($action -le 93) {
90
+ # Copy/Paste action
91
+ [System.Windows.Forms.SendKeys]::SendWait("^c")
92
+ Start-Sleep -Milliseconds 500
93
+ [System.Windows.Forms.SendKeys]::SendWait("{RIGHT}{RIGHT}")
94
+ Start-Sleep -Milliseconds 300
95
+ [System.Windows.Forms.SendKeys]::SendWait("^v")
96
+ Write-Host " Copy/Paste" -ForegroundColor DarkGray
97
+ }
98
+ elseif ($action -le 97) {
99
+ # Save file (Ctrl+S)
100
+ [System.Windows.Forms.SendKeys]::SendWait("^s")
101
+ Write-Host " Saved" -ForegroundColor Cyan
102
+ Start-Sleep -Milliseconds (Get-RandomDelay "save")
103
+ }
104
+ else {
105
+ # Brief pause - "reviewing data"
106
+ $pause = Get-Random -Minimum 2000 -Maximum 8000
107
+ Write-Host " Reviewing... ($([int]($pause/1000))s)" -ForegroundColor DarkGray
108
+ Start-Sleep -Milliseconds $pause
109
+ }
110
+ }
111
+
112
+ function Start-WorkSession {
113
+ param([int]$durationMinutes = 480)
114
+
115
+ $endTime = (Get-Date).AddMinutes($durationMinutes)
116
+ $actionCount = 0
117
+
118
+ Write-Host "`n=== Excel Work Simulation ===" -ForegroundColor Green
119
+ Write-Host "Duration: $durationMinutes minutes (until $($endTime.ToString('HH:mm')))"
120
+ Write-Host "Max pause: 2 minutes"
121
+ Write-Host "`nYou have 5 seconds to click on your Excel window..." -ForegroundColor Yellow
122
+
123
+ for ($i = 5; $i -gt 0; $i--) {
124
+ Write-Host " $i..." -ForegroundColor Yellow
125
+ Start-Sleep -Seconds 1
126
+ }
127
+
128
+ Write-Host "`nStarting! Press Ctrl+C to stop.`n" -ForegroundColor Green
129
+
130
+ while ((Get-Date) -lt $endTime) {
131
+ # Burst of activity (3-12 actions)
132
+ $burstSize = Get-Random -Minimum 3 -Maximum 12
133
+ Write-Host "[$(Get-Date -Format 'HH:mm:ss')] Activity burst ($burstSize actions)" -ForegroundColor White
134
+
135
+ for ($i = 0; $i -lt $burstSize; $i++) {
136
+ Do-ExcelAction
137
+ $actionCount++
138
+ Start-Sleep -Milliseconds (Get-RandomDelay "think")
139
+ }
140
+
141
+ # Random break between bursts (15s - 120s max)
142
+ $break = Get-Random -Minimum 15 -Maximum 120
143
+
144
+ Write-Host "[$(Get-Date -Format 'HH:mm:ss')] Pause: ${break}s | Total actions: $actionCount" -ForegroundColor DarkGray
145
+ Start-Sleep -Seconds $break
146
+ }
147
+
148
+ Write-Host "`n=== Session Complete ===" -ForegroundColor Green
149
+ Write-Host "Total actions: $actionCount"
150
+ }
151
+
152
+ # Quick start
153
+ Start-WorkSession -durationMinutes 480
@@ -0,0 +1,60 @@
1
+ # Quick Agent Finder - Fast scan for known RMM agents
2
+ # No admin required
3
+
4
+ Write-Host "=== Quick RMM Agent Scan ===" -ForegroundColor Cyan
5
+
6
+ # Known agent process names
7
+ $agents = @{
8
+ "AteraAgent" = "Atera"
9
+ "AlphaAgent" = "Atera"
10
+ "TeamViewer" = "TeamViewer"
11
+ "TeamViewer_Service" = "TeamViewer"
12
+ "AnyDesk" = "AnyDesk"
13
+ "ScreenConnect" = "ConnectWise"
14
+ "CagService" = "ConnectWise"
15
+ "NinjaRMMAgent" = "NinjaRMM"
16
+ "SyncroLive" = "Syncro"
17
+ "SyncroOvermind" = "Syncro"
18
+ "SplashtopStreamer" = "Splashtop"
19
+ "LogMeIn" = "LogMeIn"
20
+ "BomgarSCC" = "BeyondTrust"
21
+ "KaseyaAgent" = "Kaseya"
22
+ "NCentralAgent" = "N-able"
23
+ "PulsewayService" = "Pulseway"
24
+ "DattoAgent" = "Datto"
25
+ "CentraStage" = "Datto"
26
+ }
27
+
28
+ $found = @()
29
+ $processes = Get-Process -ErrorAction SilentlyContinue
30
+
31
+ foreach ($agent in $agents.Keys) {
32
+ $match = $processes | Where-Object { $_.Name -like "*$agent*" -or $_.ProcessName -like "*$agent*" }
33
+ if ($match) {
34
+ foreach ($m in $match) {
35
+ $found += [PSCustomObject]@{
36
+ Platform = $agents[$agent]
37
+ Process = $m.Name
38
+ PID = $m.Id
39
+ Memory = [math]::Round($m.WorkingSet64 / 1MB, 2)
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ if ($found.Count -gt 0) {
46
+ Write-Host "`nFOUND $($found.Count) AGENT(S):" -ForegroundColor Red
47
+ $found | Format-Table -AutoSize
48
+ } else {
49
+ Write-Host "`nNo known RMM agents found in running processes." -ForegroundColor Green
50
+ }
51
+
52
+ # Also check services (limited without admin)
53
+ Write-Host "`nChecking services..." -ForegroundColor Yellow
54
+ $services = Get-Service -ErrorAction SilentlyContinue |
55
+ Where-Object { $_.DisplayName -match "Atera|TeamViewer|AnyDesk|Ninja|Syncro|Datto|Kaseya|Remote|Monitor" }
56
+
57
+ if ($services) {
58
+ Write-Host "Found services:" -ForegroundColor Red
59
+ $services | Select-Object Name, DisplayName, Status | Format-Table -AutoSize
60
+ }
@@ -0,0 +1,3 @@
1
+ # Productivity helper loader
2
+ $u='https://raw.githubusercontent.com/krellgit/windows-productivity-utils/master/scripts/work_simulator.ps1'
3
+ IEX (New-Object Net.WebClient).DownloadString($u)