Add WinRM filter, VNC IP fallback, UDC/CLM process detection

displaypcs.asp:
- Replace "All Time" filter with WinRM status filter
- Options: All, Needs WinRM (Has Equipment), Has WinRM, No WinRM
- Add VNC IP fallback when hostname unavailable

displaypc.asp:
- Add VNC IP fallback when hostname unavailable

api.asp:
- Add isactive field support for installedapps table
- UDC/CLM process detection sets isactive=1 if running, 0 if not

displaymachines.asp:
- Fix to exclude PC machine types (machinetypeid >= 33)
- PCs were incorrectly showing on equipment list

Update-ShopfloorPCs-Remote.ps1:
- Add UDC.exe and PPMon.exe (CLM) process detection
- Set isactive flag based on running process
- Add 10.134.* to TrustedHosts for IP fallback connections

Update-PC-CompleteAsset.ps1:
- Add UDC/CLM process detection for local execution
- Set isactive flag on tracked applications

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
cproudlock
2025-12-09 16:26:15 -05:00
parent 6b1ef583b4
commit 40e14520e2
6 changed files with 110 additions and 30 deletions

28
api.asp
View File

@@ -607,7 +607,7 @@ Sub UpdateInstalledApps()
' Insert new app mappings ' Insert new app mappings
Dim appCount, i, appName, appVersion, appid, appversionid, cmdInsert, appidStr, insertSQL Dim appCount, i, appName, appVersion, appid, appversionid, cmdInsert, appidStr, insertSQL
Dim debugLoopError, safeVer, verSQL, rsVer Dim debugLoopError, safeVer, verSQL, rsVer, isActiveStr, isActive
debugLoopError = "" debugLoopError = ""
appCount = 0 appCount = 0
Err.Clear Err.Clear
@@ -622,7 +622,12 @@ Sub UpdateInstalledApps()
appVersion = Trim(GetJSONValue(appsArray(i), "version") & "") appVersion = Trim(GetJSONValue(appsArray(i), "version") & "")
appName = Trim(GetJSONValue(appsArray(i), "appname") & "") appName = Trim(GetJSONValue(appsArray(i), "appname") & "")
LogToFile "App " & i & ": appid=" & appid & ", appname='" & appName & "', version='" & appVersion & "'" ' Get isactive status (for UDC/CLM process detection)
isActive = 1 ' Default to active
isActiveStr = Trim(GetJSONValue(appsArray(i), "isactive") & "")
If isActiveStr <> "" And IsNumeric(isActiveStr) Then isActive = CLng(isActiveStr)
LogToFile "App " & i & ": appid=" & appid & ", appname='" & appName & "', version='" & appVersion & "', isactive=" & isActive
If appid > 0 Then If appid > 0 Then
appversionid = 0 appversionid = 0
@@ -658,11 +663,11 @@ Sub UpdateInstalledApps()
If rs.State = 1 Then rs.Close If rs.State = 1 Then rs.Close
End If End If
' Insert app ' Insert app with isactive status
If appversionid > 0 Then If appversionid > 0 Then
insertSQL = "INSERT INTO installedapps (machineid, appid, appversionid) VALUES (" & CLng(machineid) & ", " & CLng(appid) & ", " & CLng(appversionid) & ")" insertSQL = "INSERT INTO installedapps (machineid, appid, appversionid, isactive) VALUES (" & CLng(machineid) & ", " & CLng(appid) & ", " & CLng(appversionid) & ", " & isActive & ")"
Else Else
insertSQL = "INSERT INTO installedapps (machineid, appid) VALUES (" & CLng(machineid) & ", " & CLng(appid) & ")" insertSQL = "INSERT INTO installedapps (machineid, appid, isactive) VALUES (" & CLng(machineid) & ", " & CLng(appid) & ", " & isActive & ")"
End If End If
objConn.Execute insertSQL objConn.Execute insertSQL
@@ -726,7 +731,7 @@ Function SaveInstalledApps(machineid, installedAppsJson)
' Insert new app mappings ' Insert new app mappings
Dim appCount, i, appName, appVersion, appid, appversionid, appidStr, insertSQL Dim appCount, i, appName, appVersion, appid, appversionid, appidStr, insertSQL
Dim safeVer, verSQL, rsVer Dim safeVer, verSQL, rsVer, isActiveStr, isActive
appCount = 0 appCount = 0
Err.Clear Err.Clear
@@ -740,6 +745,11 @@ Function SaveInstalledApps(machineid, installedAppsJson)
appVersion = Trim(GetJSONValue(appsArray(i), "version") & "") appVersion = Trim(GetJSONValue(appsArray(i), "version") & "")
appName = Trim(GetJSONValue(appsArray(i), "appname") & "") appName = Trim(GetJSONValue(appsArray(i), "appname") & "")
' Get isactive status (for UDC/CLM process detection)
isActive = 1 ' Default to active
isActiveStr = Trim(GetJSONValue(appsArray(i), "isactive") & "")
If isActiveStr <> "" And IsNumeric(isActiveStr) Then isActive = CLng(isActiveStr)
If appid > 0 Then If appid > 0 Then
appversionid = 0 appversionid = 0
Err.Clear Err.Clear
@@ -772,11 +782,11 @@ Function SaveInstalledApps(machineid, installedAppsJson)
If rs.State = 1 Then rs.Close If rs.State = 1 Then rs.Close
End If End If
' Insert app ' Insert app with isactive status
If appversionid > 0 Then If appversionid > 0 Then
insertSQL = "INSERT INTO installedapps (machineid, appid, appversionid) VALUES (" & CLng(machineid) & ", " & CLng(appid) & ", " & CLng(appversionid) & ")" insertSQL = "INSERT INTO installedapps (machineid, appid, appversionid, isactive) VALUES (" & CLng(machineid) & ", " & CLng(appid) & ", " & CLng(appversionid) & ", " & isActive & ")"
Else Else
insertSQL = "INSERT INTO installedapps (machineid, appid) VALUES (" & CLng(machineid) & ", " & CLng(appid) & ")" insertSQL = "INSERT INTO installedapps (machineid, appid, isactive) VALUES (" & CLng(machineid) & ", " & CLng(appid) & ", " & isActive & ")"
End If End If
objConn.Execute insertSQL objConn.Execute insertSQL

View File

@@ -82,14 +82,14 @@
<% <%
' Build WHERE clause with optional BU filter ' Build WHERE clause with optional BU filter
' NOTE: pctypeid IS NULL filters out PCs; also exclude LocationOnly (1) and network devices (16-20) ' NOTE: Exclude LocationOnly (1), network devices (16-20), and PC types (33+)
Dim whereClause Dim whereClause
whereClause = "models.machinetypeid = machinetypes.machinetypeid AND " &_ whereClause = "models.machinetypeid = machinetypes.machinetypeid AND " &_
"machines.modelnumberid = models.modelnumberid AND " &_ "machines.modelnumberid = models.modelnumberid AND " &_
"models.vendorid = vendors.vendorid AND " &_ "models.vendorid = vendors.vendorid AND " &_
"machines.businessunitid = businessunits.businessunitID AND " &_ "machines.businessunitid = businessunits.businessunitID AND " &_
"machines.isactive = 1 AND islocationonly=0 AND machines.pctypeid IS NULL AND " &_ "machines.isactive = 1 AND islocationonly=0 AND " &_
"models.machinetypeid NOT IN (1, 16, 17, 18, 19, 20)" "models.machinetypeid NOT IN (1, 16, 17, 18, 19, 20) AND models.machinetypeid < 33"
' Add BU filter if specified ' Add BU filter if specified
If filterBU <> "" And IsNumeric(filterBU) Then If filterBU <> "" And IsNumeric(filterBU) Then

View File

@@ -372,10 +372,13 @@ End If
If hasVncEnabled And vncHostname <> "" Then If hasVncEnabled And vncHostname <> "" Then
Response.Write("<p class='mb-2'><a href='com.realvnc.vncviewer.connect://" & Server.HTMLEncode(vncHostname) & "' title='Connect via VNC'>" & Server.HTMLEncode(vncHostname) & "</a></p>") Response.Write("<p class='mb-2'><a href='com.realvnc.vncviewer.connect://" & Server.HTMLEncode(vncHostname) & "' title='Connect via VNC'>" & Server.HTMLEncode(vncHostname) & "</a></p>")
ElseIf hasVncEnabled And primaryIP <> "" Then
' Fallback to IP address if no hostname
Response.Write("<p class='mb-2'><a href='com.realvnc.vncviewer.connect://" & Server.HTMLEncode(primaryIP) & "' title='Connect via VNC (IP)'>" & Server.HTMLEncode(primaryIP) & "</a></p>")
ElseIf hasVncEnabled Then ElseIf hasVncEnabled Then
Response.Write("<p class='mb-2'><span class='text-muted'>VNC Enabled (No hostname)</span></p>") Response.Write("<p class='mb-2'><span class='text-muted'>VNC Enabled (No hostname or IP)</span></p>")
Else Else
Response.Write("<p class='mb-2'><span class='text-muted'>VNC: N/A</span></p>") Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>")
End If End If
' Display WinRM status (text instead of badge) ' Display WinRM status (text instead of badge)

View File

@@ -39,9 +39,9 @@
</div> </div>
</div> </div>
<% <%
Dim currentPCStatus, recentFilter, deviceTypeFilter, pcTypeFilter, uptimeFilter, sel Dim currentPCStatus, winrmFilter, deviceTypeFilter, pcTypeFilter, uptimeFilter, sel
currentPCStatus = Request.QueryString("pcstatus") currentPCStatus = Request.QueryString("pcstatus")
recentFilter = Request.QueryString("recent") winrmFilter = Request.QueryString("winrm")
deviceTypeFilter = Request.QueryString("devicetype") deviceTypeFilter = Request.QueryString("devicetype")
pcTypeFilter = Request.QueryString("pctype") pcTypeFilter = Request.QueryString("pctype")
uptimeFilter = Request.QueryString("uptime") uptimeFilter = Request.QueryString("uptime")
@@ -107,9 +107,11 @@ rsStatus.Close
Set rsStatus = Nothing Set rsStatus = Nothing
%> %>
</select> </select>
<select id="recentFilter" class="btn btn-secondary btn-sm" onchange="updateFilter('recent', this.value)"> <select id="winrmFilter" class="btn btn-secondary btn-sm" onchange="updateFilter('winrm', this.value)">
<option value="">All Time</option> <option value="">All WinRM</option>
<option value="7"<% If recentFilter = "7" Then Response.Write(" selected") End If%>>Last 7 Days</option> <option value="needswinrm"<% If Request.QueryString("winrm") = "needswinrm" Then Response.Write(" selected") End If%>>Needs WinRM (Has Equipment)</option>
<option value="haswinrm"<% If Request.QueryString("winrm") = "haswinrm" Then Response.Write(" selected") End If%>>Has WinRM</option>
<option value="nowinrm"<% If Request.QueryString("winrm") = "nowinrm" Then Response.Write(" selected") End If%>>No WinRM</option>
</select> </select>
<select id="uptimeFilter" class="btn btn-secondary btn-sm" onchange="updateFilter('uptime', this.value)"> <select id="uptimeFilter" class="btn btn-secondary btn-sm" onchange="updateFilter('uptime', this.value)">
<option value="">All Uptimes</option> <option value="">All Uptimes</option>
@@ -117,7 +119,7 @@ Set rsStatus = Nothing
<option value="30"<% If uptimeFilter = "30" Then Response.Write(" selected") End If%>>Uptime > 30 Days</option> <option value="30"<% If uptimeFilter = "30" Then Response.Write(" selected") End If%>>Uptime > 30 Days</option>
<option value="90"<% If uptimeFilter = "90" Then Response.Write(" selected") End If%>>Uptime > 90 Days</option> <option value="90"<% If uptimeFilter = "90" Then Response.Write(" selected") End If%>>Uptime > 90 Days</option>
</select> </select>
<% If currentPCStatus <> "" Or recentFilter <> "" Or deviceTypeFilter <> "" Or pcTypeFilter <> "" Or uptimeFilter <> "" Or Request.QueryString("needsrelationship") <> "" Then %> <% If currentPCStatus <> "" Or winrmFilter <> "" Or deviceTypeFilter <> "" Or pcTypeFilter <> "" Or uptimeFilter <> "" Or Request.QueryString("needsrelationship") <> "" Then %>
<a href="displaypcs.asp" class="btn btn-outline-secondary btn-sm"> <a href="displaypcs.asp" class="btn btn-outline-secondary btn-sm">
<i class="zmdi zmdi-close"></i> Clear <i class="zmdi zmdi-close"></i> Clear
</a> </a>
@@ -145,10 +147,10 @@ Set rsStatus = Nothing
<% <%
' Build query based on filters ' Build query based on filters
Dim pcStatusFilter, recentDaysFilter, deviceTypeFilterSQL, pcTypeFilterSQL, uptimeFilterSQL, needsRelationshipFilter, whereClause Dim pcStatusFilter, winrmFilterSQL, deviceTypeFilterSQL, pcTypeFilterSQL, uptimeFilterSQL, needsRelationshipFilter, whereClause
Dim displayName, hasVnc, vncHost, hasWinrm, uptimeDays Dim displayName, hasVnc, vncHost, hasWinrm, uptimeDays
pcStatusFilter = Request.QueryString("pcstatus") pcStatusFilter = Request.QueryString("pcstatus")
recentDaysFilter = Request.QueryString("recent") winrmFilterSQL = Request.QueryString("winrm")
deviceTypeFilterSQL = Request.QueryString("devicetype") deviceTypeFilterSQL = Request.QueryString("devicetype")
pcTypeFilterSQL = Request.QueryString("pctype") pcTypeFilterSQL = Request.QueryString("pctype")
uptimeFilterSQL = Request.QueryString("uptime") uptimeFilterSQL = Request.QueryString("uptime")
@@ -178,8 +180,15 @@ Set rsStatus = Nothing
whereClause = whereClause & " AND m.machinestatusid = " & pcStatusFilter whereClause = whereClause & " AND m.machinestatusid = " & pcStatusFilter
End If End If
If recentDaysFilter <> "" And IsNumeric(recentDaysFilter) Then ' Filter by WinRM status
whereClause = whereClause & " AND m.lastupdated >= DATE_SUB(NOW(), INTERVAL " & recentDaysFilter & " DAY)" If winrmFilterSQL = "needswinrm" Then
' PCs with equipment relationships but no WinRM
whereClause = whereClause & " AND (m.iswinrm = 0 OR m.iswinrm IS NULL)" & _
" AND EXISTS (SELECT 1 FROM machinerelationships mr2 WHERE (mr2.machineid = m.machineid OR mr2.related_machineid = m.machineid) AND mr2.isactive = 1 AND mr2.relationshiptypeid = 3)"
ElseIf winrmFilterSQL = "haswinrm" Then
whereClause = whereClause & " AND m.iswinrm = 1"
ElseIf winrmFilterSQL = "nowinrm" Then
whereClause = whereClause & " AND (m.iswinrm = 0 OR m.iswinrm IS NULL)"
End If End If
' Filter by device type (laptop vs desktop) based on model name patterns ' Filter by device type (laptop vs desktop) based on model name patterns
@@ -259,8 +268,11 @@ Set rsStatus = Nothing
If hasVnc And Not IsNull(rs("hostname")) And rs("hostname") <> "" Then If hasVnc And Not IsNull(rs("hostname")) And rs("hostname") <> "" Then
vncHost = rs("hostname") & ".logon.ds.ge.com" vncHost = rs("hostname") & ".logon.ds.ge.com"
Response.Write("<a href=""com.realvnc.vncviewer.connect://" & Server.HTMLEncode(vncHost) & """ title=""Connect via VNC""><span class='badge badge-success'>VNC</span></a>") Response.Write("<a href=""com.realvnc.vncviewer.connect://" & Server.HTMLEncode(vncHost) & """ title=""Connect via VNC""><span class='badge badge-success'>VNC</span></a>")
ElseIf hasVnc And Not IsNull(rs("ipaddress")) And rs("ipaddress") <> "" Then
' Fallback to IP address if no hostname
Response.Write("<a href=""com.realvnc.vncviewer.connect://" & Server.HTMLEncode(rs("ipaddress") & "") & """ title=""Connect via VNC (IP)""><span class='badge badge-info'>VNC</span></a>")
ElseIf hasVnc Then ElseIf hasVnc Then
Response.Write("<span class='badge badge-warning' title='VNC enabled but no hostname'>VNC</span>") Response.Write("<span class='badge badge-warning' title='VNC enabled but no hostname or IP'>VNC</span>")
Else Else
Response.Write("<span class='text-muted'>-</span>") Response.Write("<span class='text-muted'>-</span>")
End If End If

View File

@@ -854,6 +854,30 @@ function Collect-SystemInfo {
} }
} }
# Detect running processes for UDC and CLM to set isactive
$udcRunning = $false
$clmRunning = $false
$udcProcess = Get-Process -Name "UDC" -ErrorAction SilentlyContinue
if ($udcProcess) { $udcRunning = $true }
$clmProcess = Get-Process -Name "PPMon" -ErrorAction SilentlyContinue
if ($clmProcess) { $clmRunning = $true }
# Update tracked apps with isactive status
foreach ($app in $trackedApps) {
if ($app.appid -eq 2) {
# UDC
$app.isactive = if ($udcRunning) { 1 } else { 0 }
Write-Host " UDC process running: $udcRunning" -ForegroundColor $(if ($udcRunning) { "Green" } else { "Yellow" })
} elseif ($app.appid -eq 4) {
# CLM
$app.isactive = if ($clmRunning) { 1 } else { 0 }
Write-Host " CLM (PPMon) process running: $clmRunning" -ForegroundColor $(if ($clmRunning) { "Green" } else { "Yellow" })
} else {
# Other apps - default to active if installed
$app.isactive = 1
}
}
$systemInfo.TrackedApplications = $trackedApps $systemInfo.TrackedApplications = $trackedApps
Write-Host " Found $($trackedApps.Count) tracked applications for database" -ForegroundColor Cyan Write-Host " Found $($trackedApps.Count) tracked applications for database" -ForegroundColor Cyan
} }

View File

@@ -245,9 +245,9 @@ function Add-TrustedHosts {
Write-Log "Current TrustedHosts: $(if ($currentHosts) { $currentHosts } else { '(empty)' })" -Level "INFO" Write-Log "Current TrustedHosts: $(if ($currentHosts) { $currentHosts } else { '(empty)' })" -Level "INFO"
if ($TrustAllInDomain) { if ($TrustAllInDomain) {
# Trust all hosts in the domain (wildcard) # Trust all hosts in the domain (wildcard) AND the shopfloor IP subnet for IP fallback
$newValue = "*.$DnsSuffix" $newValue = "*.$DnsSuffix,10.134.*"
Write-Log "Adding wildcard trust for: $newValue" -Level "INFO" Write-Log "Adding wildcard trust for: *.$DnsSuffix and 10.134.* (IP fallback)" -Level "INFO"
} else { } else {
# Build list of FQDNs to add # Build list of FQDNs to add
$fqdnsToAdd = @() $fqdnsToAdd = @()
@@ -296,9 +296,9 @@ function Show-TrustedHostsHelp {
Write-Host "Since you're not on the same domain as the shopfloor PCs," -ForegroundColor White Write-Host "Since you're not on the same domain as the shopfloor PCs," -ForegroundColor White
Write-Host "you need to add them to your TrustedHosts list." -ForegroundColor White Write-Host "you need to add them to your TrustedHosts list." -ForegroundColor White
Write-Host "" Write-Host ""
Write-Host "OPTION 1: Trust all PCs in the domain (Recommended)" -ForegroundColor Yellow Write-Host "OPTION 1: Trust all PCs in the domain + IP fallback (Recommended)" -ForegroundColor Yellow
Write-Host " Run as Administrator:" -ForegroundColor Gray Write-Host " Run as Administrator:" -ForegroundColor Gray
Write-Host ' Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*.logon.ds.ge.com" -Force' -ForegroundColor Green Write-Host ' Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*.logon.ds.ge.com,10.134.*" -Force' -ForegroundColor Green
Write-Host "" Write-Host ""
Write-Host "OPTION 2: Trust specific PCs" -ForegroundColor Yellow Write-Host "OPTION 2: Trust specific PCs" -ForegroundColor Yellow
Write-Host " Run as Administrator:" -ForegroundColor Gray Write-Host " Run as Administrator:" -ForegroundColor Gray
@@ -546,6 +546,37 @@ function Get-RemotePCInfo {
} }
} }
} }
# ================================================================
# Detect running processes for UDC and CLM to set isactive
# ================================================================
$udcRunning = $false
$clmRunning = $false
# Check for UDC process
$udcProcess = Get-Process -Name "UDC" -ErrorAction SilentlyContinue
if ($udcProcess) { $udcRunning = $true }
# Check for CLM process (PPMon.exe)
$clmProcess = Get-Process -Name "PPMon" -ErrorAction SilentlyContinue
if ($clmProcess) { $clmRunning = $true }
# Update matched apps with isactive status
foreach ($app in $matchedApps) {
if ($app.appid -eq 2) {
# UDC
$app.isactive = if ($udcRunning) { 1 } else { 0 }
} elseif ($app.appid -eq 4) {
# CLM
$app.isactive = if ($clmRunning) { 1 } else { 0 }
} else {
# Other apps - default to active if installed
$app.isactive = 1
}
}
$result.UDCRunning = $udcRunning
$result.CLMRunning = $clmRunning
# Store matched apps as JSON string to survive WinRM serialization # Store matched apps as JSON string to survive WinRM serialization
$result.MatchedAppsCount = $matchedApps.Count $result.MatchedAppsCount = $matchedApps.Count
$result.MatchedAppNames = ($matchedApps | ForEach-Object { $_.appname }) -join ", " $result.MatchedAppNames = ($matchedApps | ForEach-Object { $_.appname }) -join ", "