Add eDNC-Fix API endpoints and displaypc.asp integration
API endpoints: - logDNCEvent: Log events from eDNC-Fix PowerShell script - getDNCStats: Get all eDNC installations and stats Database tables (sql/ednc_tables.sql): - ednc_logs: Event log entries - ednc_installations: Per-hostname tracking displaypc.asp: - Shows eDNC-Fix stats in Applications tab if installed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
153
api.asp
@@ -49,6 +49,10 @@ Select Case action
|
|||||||
GetRecordedIP()
|
GetRecordedIP()
|
||||||
Case "updateMachinePositions"
|
Case "updateMachinePositions"
|
||||||
UpdateMachinePositions()
|
UpdateMachinePositions()
|
||||||
|
Case "logDNCEvent"
|
||||||
|
LogDNCEvent()
|
||||||
|
Case "getDNCStats"
|
||||||
|
GetDNCStats()
|
||||||
Case Else
|
Case Else
|
||||||
SendError "Invalid action: " & action
|
SendError "Invalid action: " & action
|
||||||
End Select
|
End Select
|
||||||
@@ -2541,4 +2545,153 @@ Sub UpdateMachinePositions()
|
|||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
' ============================================================================
|
||||||
|
' eDNC SPECIAL CHARACTER FIX - LOGGING
|
||||||
|
' ============================================================================
|
||||||
|
|
||||||
|
Sub LogDNCEvent()
|
||||||
|
On Error Resume Next
|
||||||
|
|
||||||
|
' Get parameters
|
||||||
|
Dim hostname, filename, eventAction, bytesRemoved, version, message, watchFolder, fileFilter
|
||||||
|
hostname = Trim(Request.Form("hostname") & "")
|
||||||
|
filename = Trim(Request.Form("filename") & "")
|
||||||
|
eventAction = Trim(Request.Form("eventType") & "")
|
||||||
|
bytesRemoved = Request.Form("bytesRemoved")
|
||||||
|
version = Trim(Request.Form("version") & "")
|
||||||
|
message = Trim(Request.Form("message") & "")
|
||||||
|
watchFolder = Trim(Request.Form("watchFolder") & "")
|
||||||
|
fileFilter = Trim(Request.Form("fileFilter") & "")
|
||||||
|
|
||||||
|
' Validate required fields
|
||||||
|
If hostname = "" Or eventAction = "" Then
|
||||||
|
SendError "hostname and eventType are required"
|
||||||
|
Exit Sub
|
||||||
|
End If
|
||||||
|
|
||||||
|
' Sanitize inputs
|
||||||
|
Dim safeHostname, safeFilename, safeAction, safeVersion, safeMessage, safeWatchFolder, safeFileFilter
|
||||||
|
safeHostname = Replace(hostname, "'", "''")
|
||||||
|
safeFilename = Replace(filename, "'", "''")
|
||||||
|
safeAction = Replace(eventAction, "'", "''")
|
||||||
|
safeVersion = Replace(version, "'", "''")
|
||||||
|
safeMessage = Replace(message, "'", "''")
|
||||||
|
safeWatchFolder = Replace(watchFolder, "'", "''")
|
||||||
|
safeFileFilter = Replace(fileFilter, "'", "''")
|
||||||
|
|
||||||
|
' Default bytesRemoved to 0 if not numeric
|
||||||
|
If Not IsNumeric(bytesRemoved) Or bytesRemoved = "" Then bytesRemoved = 0
|
||||||
|
|
||||||
|
' Insert log entry
|
||||||
|
Dim insertSQL
|
||||||
|
insertSQL = "INSERT INTO ednc_logs (hostname, filename, action, bytes_removed, version, message) " & _
|
||||||
|
"VALUES ('" & safeHostname & "', '" & safeFilename & "', '" & safeAction & "', " & _
|
||||||
|
CLng(bytesRemoved) & ", '" & safeVersion & "', '" & safeMessage & "')"
|
||||||
|
objConn.Execute insertSQL
|
||||||
|
|
||||||
|
If Err.Number <> 0 Then
|
||||||
|
SendError "Failed to log event: " & Err.Description
|
||||||
|
Exit Sub
|
||||||
|
End If
|
||||||
|
|
||||||
|
' Update or insert installation record
|
||||||
|
Dim checkSQL, rsCheck
|
||||||
|
checkSQL = "SELECT installid, total_cleaned, total_failed FROM ednc_installations WHERE hostname = '" & safeHostname & "'"
|
||||||
|
Set rsCheck = objConn.Execute(checkSQL)
|
||||||
|
|
||||||
|
If rsCheck.EOF Then
|
||||||
|
' New installation - INSERT
|
||||||
|
Dim installSQL
|
||||||
|
installSQL = "INSERT INTO ednc_installations (hostname, version, watch_folder, file_filter, total_cleaned, total_failed) " & _
|
||||||
|
"VALUES ('" & safeHostname & "', '" & safeVersion & "', '" & safeWatchFolder & "', '" & safeFileFilter & "', "
|
||||||
|
If eventAction = "cleaned" Then
|
||||||
|
installSQL = installSQL & "1, 0)"
|
||||||
|
ElseIf eventAction = "failed" Or eventAction = "error" Then
|
||||||
|
installSQL = installSQL & "0, 1)"
|
||||||
|
Else
|
||||||
|
installSQL = installSQL & "0, 0)"
|
||||||
|
End If
|
||||||
|
objConn.Execute installSQL
|
||||||
|
Else
|
||||||
|
' Existing installation - UPDATE
|
||||||
|
Dim totalCleaned, totalFailed, updateSQL
|
||||||
|
totalCleaned = CLng(rsCheck("total_cleaned"))
|
||||||
|
totalFailed = CLng(rsCheck("total_failed"))
|
||||||
|
|
||||||
|
If eventAction = "cleaned" Then
|
||||||
|
totalCleaned = totalCleaned + 1
|
||||||
|
ElseIf eventAction = "failed" Or eventAction = "error" Then
|
||||||
|
totalFailed = totalFailed + 1
|
||||||
|
End If
|
||||||
|
|
||||||
|
updateSQL = "UPDATE ednc_installations SET " & _
|
||||||
|
"version = '" & safeVersion & "', " & _
|
||||||
|
"last_seen = NOW(), " & _
|
||||||
|
"total_cleaned = " & totalCleaned & ", " & _
|
||||||
|
"total_failed = " & totalFailed
|
||||||
|
If safeWatchFolder <> "" Then
|
||||||
|
updateSQL = updateSQL & ", watch_folder = '" & safeWatchFolder & "'"
|
||||||
|
End If
|
||||||
|
If safeFileFilter <> "" Then
|
||||||
|
updateSQL = updateSQL & ", file_filter = '" & safeFileFilter & "'"
|
||||||
|
End If
|
||||||
|
updateSQL = updateSQL & " WHERE hostname = '" & safeHostname & "'"
|
||||||
|
objConn.Execute updateSQL
|
||||||
|
End If
|
||||||
|
rsCheck.Close
|
||||||
|
Set rsCheck = Nothing
|
||||||
|
|
||||||
|
' Send success response
|
||||||
|
Response.Write "{""success"":true,""message"":""Event logged""}"
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Sub GetDNCStats()
|
||||||
|
On Error Resume Next
|
||||||
|
|
||||||
|
' Get installations with recent activity
|
||||||
|
Dim sql, rs
|
||||||
|
sql = "SELECT i.hostname, i.version, i.watch_folder, i.file_filter, " & _
|
||||||
|
"i.first_seen, i.last_seen, i.is_active, i.total_cleaned, i.total_failed, " & _
|
||||||
|
"(SELECT COUNT(*) FROM ednc_logs l WHERE l.hostname = i.hostname AND l.created > DATE_SUB(NOW(), INTERVAL 24 HOUR)) AS events_24h " & _
|
||||||
|
"FROM ednc_installations i ORDER BY i.last_seen DESC"
|
||||||
|
|
||||||
|
Set rs = objConn.Execute(sql)
|
||||||
|
|
||||||
|
If Err.Number <> 0 Then
|
||||||
|
SendError "Database error: " & Err.Description
|
||||||
|
Exit Sub
|
||||||
|
End If
|
||||||
|
|
||||||
|
' Build JSON response
|
||||||
|
Dim json, first
|
||||||
|
json = "{""success"":true,""installations"":["
|
||||||
|
first = True
|
||||||
|
|
||||||
|
Do While Not rs.EOF
|
||||||
|
If Not first Then json = json & ","
|
||||||
|
first = False
|
||||||
|
|
||||||
|
json = json & "{" & _
|
||||||
|
"""hostname"":""" & (rs("hostname") & "") & """," & _
|
||||||
|
"""version"":""" & (rs("version") & "") & """," & _
|
||||||
|
"""watchFolder"":""" & Replace(rs("watch_folder") & "", "\", "\\") & """," & _
|
||||||
|
"""fileFilter"":""" & (rs("file_filter") & "") & """," & _
|
||||||
|
"""firstSeen"":""" & (rs("first_seen") & "") & """," & _
|
||||||
|
"""lastSeen"":""" & (rs("last_seen") & "") & """," & _
|
||||||
|
"""isActive"":" & rs("is_active") & "," & _
|
||||||
|
"""totalCleaned"":" & rs("total_cleaned") & "," & _
|
||||||
|
"""totalFailed"":" & rs("total_failed") & "," & _
|
||||||
|
"""events24h"":" & rs("events_24h") & _
|
||||||
|
"}"
|
||||||
|
rs.MoveNext
|
||||||
|
Loop
|
||||||
|
|
||||||
|
json = json & "]}"
|
||||||
|
|
||||||
|
rs.Close
|
||||||
|
Set rs = Nothing
|
||||||
|
|
||||||
|
Response.Write json
|
||||||
|
End Sub
|
||||||
|
|
||||||
%>
|
%>
|
||||||
|
|||||||
@@ -733,6 +733,73 @@ End If
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- eDNC Special Character Fix Stats -->
|
||||||
|
<%
|
||||||
|
'=============================================================================
|
||||||
|
' eDNC-Fix Installation Stats for this PC
|
||||||
|
'=============================================================================
|
||||||
|
Dim edncSQL, rsEdnc, hasEdnc
|
||||||
|
hasEdnc = False
|
||||||
|
edncSQL = "SELECT i.version, i.watch_folder, i.file_filter, i.first_seen, i.last_seen, " & _
|
||||||
|
"i.total_cleaned, i.total_failed, " & _
|
||||||
|
"(SELECT COUNT(*) FROM ednc_logs l WHERE l.hostname = i.hostname AND l.created > DATE_SUB(NOW(), INTERVAL 24 HOUR)) AS events_24h, " & _
|
||||||
|
"(SELECT MAX(created) FROM ednc_logs l WHERE l.hostname = i.hostname AND l.action = 'cleaned') AS last_cleaned " & _
|
||||||
|
"FROM ednc_installations i " & _
|
||||||
|
"INNER JOIN machines m ON UPPER(i.hostname) = UPPER(m.hostname) " & _
|
||||||
|
"WHERE m.machineid = ?"
|
||||||
|
Set rsEdnc = ExecuteParameterizedQuery(objConn, edncSQL, Array(machineid))
|
||||||
|
If Not rsEdnc.EOF Then
|
||||||
|
hasEdnc = True
|
||||||
|
%>
|
||||||
|
<h6 class="mt-4 mb-3"><i class="zmdi zmdi-settings"></i> eDNC Special Character Fix</h6>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-sm table-bordered">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="font-weight-bold" width="35%">Version</td>
|
||||||
|
<td><%= Server.HTMLEncode(rsEdnc("version") & "") %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-weight-bold">Watch Folder</td>
|
||||||
|
<td><code><%= Server.HTMLEncode(rsEdnc("watch_folder") & "") %></code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-weight-bold">File Filter</td>
|
||||||
|
<td><code><%= Server.HTMLEncode(rsEdnc("file_filter") & "") %></code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-weight-bold">First Seen</td>
|
||||||
|
<td><%= rsEdnc("first_seen") %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-weight-bold">Last Active</td>
|
||||||
|
<td><%= rsEdnc("last_seen") %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-weight-bold">Files Cleaned (Total)</td>
|
||||||
|
<td><span class="badge badge-success"><%= rsEdnc("total_cleaned") %></span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-weight-bold">Files Failed (Total)</td>
|
||||||
|
<td><span class="badge badge-<%= IIf(CLng(rsEdnc("total_failed") & "0") > 0, "danger", "secondary") %>"><%= rsEdnc("total_failed") %></span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-weight-bold">Events (Last 24h)</td>
|
||||||
|
<td><%= rsEdnc("events_24h") %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-weight-bold">Last File Cleaned</td>
|
||||||
|
<td><%= rsEdnc("last_cleaned") & "" %></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<%
|
||||||
|
End If
|
||||||
|
rsEdnc.Close
|
||||||
|
Set rsEdnc = Nothing
|
||||||
|
%>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
BIN
images/12.jpg
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 184 KiB |
BIN
images/15.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
images/Thumbs.db
BIN
images/applications/FAMS.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 178 KiB |
BIN
images/applications/gelearning.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
images/applications/gensuite.png
Normal file
|
After Width: | Height: | Size: 228 KiB |
BIN
images/applications/impact.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
images/applications/m365.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
images/applications/maximo.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
images/applications/rightcrowd.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
images/applications/travel.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
images/applications/workday.png
Normal file
|
After Width: | Height: | Size: 682 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 98 KiB |
BIN
images/machines/7107sf.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
images/machines/Cisco9120.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
images/machines/IDF.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
images/machines/OptiPlex-7070.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
images/machines/Optiplex-7000.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
images/machines/abtech-eas1000.png
Normal file
|
After Width: | Height: | Size: 152 KiB |
BIN
images/machines/abtech-eas1000.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
images/machines/keyence-vr3100.png
Normal file
|
After Width: | Height: | Size: 208 KiB |
BIN
images/machines/latitude5440.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
images/machines/leandrum.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
images/machines/phoenixbroach.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
images/machines/precision5560.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
images/machines/rb2.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 1.7 MiB |
BIN
images/printers/LaserJet-Pro-M252dw.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
images/printers/Laserjet-Pro-M251nw.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 380 KiB After Width: | Height: | Size: 350 KiB |
41
sql/ednc_tables.sql
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- eDNC Special Character Fix - Database Tables
|
||||||
|
-- Run on PRODUCTION database to enable eDNC logging
|
||||||
|
-- Created: 2025-12-12
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Log individual events (cleaned, failed, started, stopped, etc.)
|
||||||
|
CREATE TABLE IF NOT EXISTS ednc_logs (
|
||||||
|
logid INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
hostname VARCHAR(50) NOT NULL,
|
||||||
|
filename VARCHAR(255) NOT NULL,
|
||||||
|
action ENUM('cleaned', 'ok', 'failed', 'error', 'started', 'stopped') NOT NULL,
|
||||||
|
bytes_removed INT DEFAULT 0,
|
||||||
|
version VARCHAR(20),
|
||||||
|
message VARCHAR(500),
|
||||||
|
created DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX idx_hostname (hostname),
|
||||||
|
INDEX idx_created (created),
|
||||||
|
INDEX idx_action (action)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Track installations per PC
|
||||||
|
CREATE TABLE IF NOT EXISTS ednc_installations (
|
||||||
|
installid INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
hostname VARCHAR(50) NOT NULL UNIQUE,
|
||||||
|
version VARCHAR(20),
|
||||||
|
watch_folder VARCHAR(255),
|
||||||
|
file_filter VARCHAR(50),
|
||||||
|
first_seen DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
last_seen DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
is_active TINYINT(1) DEFAULT 1,
|
||||||
|
total_cleaned INT DEFAULT 0,
|
||||||
|
total_failed INT DEFAULT 0,
|
||||||
|
INDEX idx_hostname (hostname),
|
||||||
|
INDEX idx_active (is_active)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Verify tables created
|
||||||
|
SELECT 'ednc_logs' AS table_name, COUNT(*) AS row_count FROM ednc_logs
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'ednc_installations', COUNT(*) FROM ednc_installations;
|
||||||