-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEnable-NahimicNotifications.ps1
More file actions
219 lines (180 loc) · 8.48 KB
/
Copy pathEnable-NahimicNotifications.ps1
File metadata and controls
219 lines (180 loc) · 8.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Installs a scheduled task that monitors for Nahimic file resurrection
and fires a Windows toast notification if any are detected.
.DESCRIPTION
Installs two components:
1. A monitoring script saved to disk that checks for Nahimic files
and sends a toast notification if any are found
2. A scheduled task that runs the monitor every 30 minutes
The notification includes a timestamp and file count, useful for
correlating detections with Windows Update activity.
.NOTES
To uninstall:
Unregister-ScheduledTask -TaskName "NahimicMonitor" -Confirm:$false
Remove-Item "C:\ProgramData\NahimicMonitor\Monitor-Nahimic.ps1" -Force
To check task history:
Get-ScheduledTaskInfo -TaskName "NahimicMonitor"
#>
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Continue'
$taskName = "NahimicMonitor"
$scriptDir = "C:\ProgramData\NahimicMonitor"
$scriptPath = "$scriptDir\Monitor-Nahimic.ps1"
$logPath = "$scriptDir\detections.log"
# -- The monitor script --------------------------------------------------------
# This gets saved to disk and executed by the scheduled task.
# It runs as the current user (not SYSTEM) so toast notifications are visible.
$monitorScript = @'
$logPath = "C:\ProgramData\NahimicMonitor\detections.log"
# Check for Nahimic files
$nahimicFiles = @(Get-ChildItem "C:\Windows\System32\Nahimic*" -ErrorAction SilentlyContinue)
$nahimicDrivers = @(Get-ChildItem "C:\Windows\System32\drivers\Nahimic*" -ErrorAction SilentlyContinue)
$nahimicServices = @(Get-Service -Name "Nahimic*" -ErrorAction SilentlyContinue |
Where-Object { $_.Status -eq 'Running' })
$allFindings = $nahimicFiles + $nahimicDrivers
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
if ($allFindings.Count -eq 0 -and $nahimicServices.Count -eq 0) {
exit 0
}
# Build detail string
$details = [System.Collections.Generic.List[string]]::new()
if ($nahimicFiles.Count -gt 0) {
$details.Add("$($nahimicFiles.Count) file(s) in System32")
}
if ($nahimicDrivers.Count -gt 0) {
$details.Add("$($nahimicDrivers.Count) driver(s) in System32\drivers")
}
if ($nahimicServices.Count -gt 0) {
$details.Add("$($nahimicServices.Count) service(s) running")
}
$detailString = $details -join ", "
# Log detection
$logEntry = "[$timestamp] DETECTED: $detailString"
Add-Content -Path $logPath -Value $logEntry -Encoding UTF8
# Fire toast notification
try {
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
$fileList = ($allFindings | Select-Object -First 5 | ForEach-Object { $_.Name }) -join ", "
if ($allFindings.Count -gt 5) { $fileList += " ..." }
$template = @"
<toast duration="long">
<visual>
<binding template="ToastGeneric">
<text>⚠ Nahimic has returned</text>
<text>$detailString detected at $timestamp</text>
<text>$fileList</text>
</binding>
</visual>
<actions>
<action content="Open Log" activationType="protocol" arguments="file:///C:/ProgramData/NahimicMonitor/detections.log"/>
</actions>
</toast>
"@
$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
$xml.LoadXml($template)
$toast = [Windows.UI.Notifications.ToastNotification]::new($xml)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("Nahimic Monitor").Show($toast)
}
catch {
# Toast failed - log it but don't crash
Add-Content -Path $logPath -Value "[$timestamp] Toast notification failed: $_" -Encoding UTF8
}
'@
# -- Install -------------------------------------------------------------------
Write-Host ""
Write-Host "============================================================" -ForegroundColor Magenta
Write-Host " Nahimic Monitor - Installation" -ForegroundColor Magenta
Write-Host "============================================================" -ForegroundColor Magenta
Write-Host ""
# Create directory and save monitor script
if (-not (Test-Path $scriptDir)) {
New-Item -Path $scriptDir -ItemType Directory -Force | Out-Null
}
Set-Content -Path $scriptPath -Value $monitorScript -Encoding UTF8
Write-Host " OK Monitor script saved to: $scriptPath" -ForegroundColor Green
# Create log file if it doesn't exist
if (-not (Test-Path $logPath)) {
$header = "Nahimic Monitor - Detection Log`nInstalled: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')`n$('-' * 60)"
Set-Content -Path $logPath -Value $header -Encoding UTF8
}
Write-Host " OK Detection log: $logPath" -ForegroundColor Green
# Remove existing task if present
$existing = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
if ($existing) {
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
Write-Host " -- Removed existing task" -ForegroundColor DarkGray
}
# The task runs as the current logged-in user so toast notifications are visible
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-NonInteractive -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$scriptPath`""
# Run at logon, then repeat every 30 minutes indefinitely
$triggerLogon = New-ScheduledTaskTrigger -AtLogOn -User $currentUser
$settings = New-ScheduledTaskSettingsSet `
-ExecutionTimeLimit (New-TimeSpan -Minutes 5) `
-MultipleInstances IgnoreNew `
-StartWhenAvailable `
-RunOnlyIfNetworkAvailable:$false
$principal = New-ScheduledTaskPrincipal `
-UserId $currentUser `
-LogonType Interactive `
-RunLevel Highest
$task = Register-ScheduledTask `
-TaskName $taskName `
-Action $action `
-Trigger $triggerLogon `
-Principal $principal `
-Settings $settings `
-Description "Monitors for Nahimic file resurrection and fires a toast notification if detected. See $logPath for history." `
-Force
# Add the 30-minute repeating trigger via XML (New-ScheduledTaskTrigger doesn't support repetition cleanly)
$taskXml = [xml]($task | Export-ScheduledTask)
$ns = "http://schemas.microsoft.com/windows/2004/02/mit/task"
$triggerNode = $taskXml.Task.Triggers.LogonTrigger
$repetition = $taskXml.CreateElement("Repetition", $ns)
$interval = $taskXml.CreateElement("Interval", $ns)
$interval.InnerText = "PT30M"
$duration = $taskXml.CreateElement("Duration", $ns)
$duration.InnerText = "P9999D"
$stopAtEnd = $taskXml.CreateElement("StopAtDurationEnd", $ns)
$stopAtEnd.InnerText = "false"
$repetition.AppendChild($interval) | Out-Null
$repetition.AppendChild($duration) | Out-Null
$repetition.AppendChild($stopAtEnd) | Out-Null
$triggerNode.AppendChild($repetition) | Out-Null
# Re-register with the updated XML
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
Register-ScheduledTask -TaskName $taskName -Xml $taskXml.OuterXml -Force | Out-Null
Write-Host " OK Scheduled task installed: $taskName" -ForegroundColor Green
Write-Host " Runs at logon, then every 30 minutes" -ForegroundColor DarkGray
Write-Host " Running as: $currentUser" -ForegroundColor DarkGray
# Run it once immediately so you know it works
Write-Host ""
Write-Host " Running monitor now to verify..." -ForegroundColor Cyan
& powershell.exe -NonInteractive -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File $scriptPath
# Check log for immediate result
Start-Sleep -Seconds 2
$lastLog = Get-Content $logPath -Tail 3 -ErrorAction SilentlyContinue
if ($lastLog -match "DETECTED") {
Write-Host " !! Nahimic detected on first run - check notification and log" -ForegroundColor Yellow
}
else {
Write-Host " OK First run clean - no Nahimic detected" -ForegroundColor Green
}
Write-Host ""
Write-Host "============================================================" -ForegroundColor Magenta
Write-Host " Installation complete." -ForegroundColor Magenta
Write-Host ""
Write-Host " You will receive a toast notification if Nahimic" -ForegroundColor White
Write-Host " returns. Detections are logged to:" -ForegroundColor White
Write-Host " $logPath" -ForegroundColor Cyan
Write-Host ""
Write-Host " To uninstall:" -ForegroundColor White
Write-Host " Unregister-ScheduledTask -TaskName '$taskName' -Confirm:`$false" -ForegroundColor Cyan
Write-Host " Remove-Item '$scriptDir' -Recurse -Force" -ForegroundColor Cyan
Write-Host "============================================================" -ForegroundColor Magenta
Write-Host ""