Files
powershell-scripts/docs/DATA_COLLECTION_PARITY.html
cproudlock 7d3519f613 Add comprehensive documentation and update deployment paths
Documentation:
- Add ShopDB-API.md with full API reference (all GET/POST endpoints)
- Add detailed docs for Update-ShopfloorPCs-Remote, Invoke-RemoteMaintenance, Update-PC-CompleteAsset
- Add DATA_COLLECTION_PARITY.md comparing local vs remote data collection
- Add HTML versions of all documentation with styled code blocks
- Document software deployment mechanism and how to add new apps
- Document deprecated scripts (Invoke-RemoteAssetCollection, Install-KioskApp)

Script Updates:
- Update deployment source paths to network share (tsgwp00525.wjs.geaerospace.net)
  - InstallDashboard: \\...\scripts\Dashboard\GEAerospaceDashboardSetup.exe
  - InstallLobbyDisplay: \\...\scripts\LobbyDisplay\GEAerospaceLobbyDisplaySetup.exe
  - UpdateEMxAuthToken: \\...\scripts\eMx\eMxInfo.txt
  - DeployUDCWebServerConfig: \\...\scripts\UDC\udc_webserver_settings.json
- Update machine network detection to include 100.0.0.* for CMM cases
- Rename PC Type #9 from "Part Marker" to "Inspection"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 11:45:00 -05:00

1115 lines
30 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Data Collection Parity Reference</title>
<style>
* {
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
max-width: 900px;
margin: 0 auto;
padding: 20px 40px;
background-color: #ffffff;
color: #333;
}
h1 {
color: #1a5276;
border-bottom: 3px solid #1a5276;
padding-bottom: 10px;
margin-top: 0;
}
h2 {
color: #2874a6;
border-bottom: 2px solid #d5dbdb;
padding-bottom: 8px;
margin-top: 40px;
}
h3 {
color: #2e86ab;
margin-top: 30px;
}
h4 {
color: #5d6d7e;
margin-top: 25px;
}
a {
color: #2980b9;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
code {
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
background-color: #f4f4f4;
padding: 2px 6px;
border-radius: 3px;
font-size: 0.9em;
border: 1px solid #e1e1e1;
}
pre {
background-color: #2d2d2d;
color: #f8f8f2;
padding: 15px 20px;
border-radius: 6px;
overflow-x: auto;
font-family: 'Cascadia Mono', 'JetBrains Mono', 'Fira Code', 'Source Code Pro', 'DejaVu Sans Mono', 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 14px;
line-height: 1.4;
border: 1px solid #444;
margin: 15px 0;
-webkit-font-feature-settings: "liga" 0;
font-feature-settings: "liga" 0;
letter-spacing: 0;
}
pre code {
background-color: transparent;
padding: 0;
border: none;
color: inherit;
font-size: inherit;
}
table {
border-collapse: collapse;
width: 100%;
margin: 15px 0;
font-size: 14px;
}
th, td {
border: 1px solid #ddd;
padding: 10px 12px;
text-align: left;
}
th {
background-color: #34495e;
color: white;
font-weight: 600;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
tr:hover {
background-color: #f1f1f1;
}
ul, ol {
padding-left: 25px;
}
li {
margin-bottom: 5px;
}
blockquote {
border-left: 4px solid #3498db;
margin: 15px 0;
padding: 10px 20px;
background-color: #f8f9fa;
color: #555;
}
hr {
border: none;
border-top: 2px solid #eee;
margin: 30px 0;
}
.toc {
background-color: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 6px;
padding: 20px;
margin-bottom: 30px;
}
.toc h2 {
margin-top: 0;
border-bottom: none;
font-size: 1.2em;
}
.toc ul {
list-style-type: none;
padding-left: 0;
}
.toc li {
margin-bottom: 8px;
}
.toc a {
color: #2c3e50;
}
.note {
background-color: #fff3cd;
border-left: 4px solid #ffc107;
padding: 10px 15px;
margin: 15px 0;
}
.warning {
background-color: #f8d7da;
border-left: 4px solid #dc3545;
padding: 10px 15px;
margin: 15px 0;
}
@media print {
body {
max-width: 100%;
padding: 20px;
}
pre {
white-space: pre-wrap;
word-wrap: break-word;
}
h2 {
page-break-before: auto;
}
pre, table {
page-break-inside: avoid;
}
}
</style>
</head>
<body>
<h1 id="data-collection-parity-reference">Data Collection Parity Reference</h1>
<p>Comprehensive comparison of data fields collected by the remote and local PowerShell scripts, including collection methods and API mapping.</p>
<h2 id="table-of-contents">Table of Contents</h2>
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#scripts-compared">Scripts Compared</a></li>
<li><a href="#quick-reference-tables">Quick Reference Tables</a></li>
<li><a href="#detailed-field-reference">Detailed Field Reference</a></li>
<li><a href="#collection-methods">Collection Methods</a></li>
<li><a href="#api-parameter-mapping">API Parameter Mapping</a></li>
<li><a href="#testing-parity">Testing Parity</a></li>
<li><a href="#known-differences">Known Differences</a></li>
</ul>
<hr>
<h2 id="overview">Overview</h2>
<p>Both the remote and local collection scripts are designed to collect the same data fields for shopfloor PCs. This document provides a comprehensive reference for what data is collected, how it's collected, and any differences between the two approaches.</p>
<p><strong>Goal:</strong> Any field collected by one script should also be collected by the other (where technically feasible).</p>
<hr>
<h2 id="scripts-compared">Scripts Compared</h2>
<table>
<thead><tr>
<th>Aspect</th>
<th>Remote Script</th>
<th>Local Script</th>
</tr></thead>
<tbody>
<tr>
<td><strong>Name</strong></td>
<td>Update-ShopfloorPCs-Remote.ps1</td>
<td>Update-PC-CompleteAsset.ps1</td>
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>S:\dt\shopfloor\scripts\remote-execution\</code></td>
<td><code>S:\dt\shopfloor\scripts\complete-asset\</code></td>
</tr>
<tr>
<td><strong>Execution</strong></td>
<td>From admin workstation via WinRM</td>
<td>Directly on target PC</td>
</tr>
<tr>
<td><strong>Context</strong></td>
<td>SYSTEM via WinRM</td>
<td>Local user or SYSTEM</td>
</tr>
<tr>
<td><strong>Batch Support</strong></td>
<td>Yes (many PCs)</td>
<td>No (one PC at a time)</td>
</tr>
<tr>
<td><strong>WinRM Required</strong></td>
<td>Yes</td>
<td>No</td>
</tr>
</tbody></table>
<hr>
<h2 id="quick-reference-tables">Quick Reference Tables</h2>
<h3 id="complete-field-parity-status">Complete Field Parity Status</h3>
<table>
<thead><tr>
<th>Category</th>
<th>Field</th>
<th>Remote</th>
<th>Local</th>
<th>Parity</th>
</tr></thead>
<tbody>
<tr>
<td><strong>System</strong></td>
<td>Hostname</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Serial Number</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Service Tag</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Manufacturer</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Model</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Total Physical Memory</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Domain Role</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>OS Version</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Last Boot Time</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Current Time Zone</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Logged In User</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>PC Type</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Machine No</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td><strong>DNC</strong></td>
<td>Site</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>CNC</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>NcIF</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Host Type</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>FTP Primary</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>FTP Secondary</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td><strong>GE Registry</strong></td>
<td>32-bit Present</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>64-bit Present</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Dual Path Enabled</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Path 1 Name</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Path 2 Name</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td><strong>Network</strong></td>
<td>Interface Name</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>IP Address</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Subnet Mask</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Default Gateway</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>MAC Address</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Is DHCP</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Is Active</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Is Machine Network</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Is Primary</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td><strong>Apps</strong></td>
<td>Serial Ports</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Has VNC</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>All Installed Apps</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>Tracked Applications</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>UDC Running</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td></td>
<td>CLM Running</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td><strong>Printer</strong></td>
<td>Default Printer FQDN</td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td>
</tr>
<tr>
<td><strong>Local Only</strong></td>
<td>V-Drive Access</td>
<td>&#10007;</td>
<td>&#10003;</td>
<td>N/A</td>
</tr>
<tr>
<td></td>
<td>C:\Apps Folder</td>
<td>&#10007;</td>
<td>&#10003;</td>
<td>N/A</td>
</tr>
</tbody></table>
<p><strong>Legend:</strong> &#10003; = Collected, &#10007; = Not collected, N/A = Not applicable</p>
<hr>
<h2 id="detailed-field-reference">Detailed Field Reference</h2>
<h3 id="basic-system-information">Basic System Information</h3>
<h4 id="hostname">Hostname</h4>
<ul>
<li><strong>Description:</strong> Computer name of the target PC</li>
<li><strong>Remote:</strong> <code>$env:COMPUTERNAME</code> inside Invoke-Command scriptblock</li>
<li><strong>Local:</strong> <code>$env:COMPUTERNAME</code></li>
<li><strong>API Parameter:</strong> <code>hostname</code></li>
<li><strong>Example:</strong> <code>SHOPFLOOR-PC01</code></li>
</ul>
<h4 id="serial-number">Serial Number</h4>
<ul>
<li><strong>Description:</strong> BIOS serial number (Dell service tag)</li>
<li><strong>Remote:</strong> <code>(Get-CimInstance -Class CIM_BIOSElement).SerialNumber</code></li>
<li><strong>Local:</strong> <code>(Get-CimInstance -Class CIM_BIOSElement).SerialNumber</code></li>
<li><strong>API Parameter:</strong> <code>serialNumber</code></li>
<li><strong>Example:</strong> <code>ABC1234567</code></li>
</ul>
<h4 id="service-tag">Service Tag</h4>
<ul>
<li><strong>Description:</strong> Dell service tag (same as serial for Dell systems)</li>
<li><strong>Remote:</strong> Same as SerialNumber</li>
<li><strong>Local:</strong> Same as SerialNumber</li>
<li><strong>API Parameter:</strong> <code>serviceTag</code></li>
<li><strong>Example:</strong> <code>ABC1234567</code></li>
</ul>
<h4 id="total-physical-memory">Total Physical Memory</h4>
<ul>
<li><strong>Description:</strong> Total RAM in gigabytes</li>
<li><strong>Remote:</strong> <code>[Math]::Round($computerSystem.TotalPhysicalMemory / 1GB, 2)</code></li>
<li><strong>Local:</strong> <code>[Math]::Round($computerSystem.TotalPhysicalMemory / 1GB, 2)</code></li>
<li><strong>API Parameter:</strong> <code>totalPhysicalMemory</code></li>
<li><strong>Example:</strong> <code>16.0</code></li>
</ul>
<h4 id="domain-role">Domain Role</h4>
<ul>
<li><strong>Description:</strong> Domain membership type</li>
<li><strong>Remote:</strong> <code>$computerSystem.DomainRole</code></li>
<li><strong>Local:</strong> <code>$computerSystem.DomainRole</code></li>
<li><strong>API Parameter:</strong> <code>domainRole</code></li>
<li><strong>Values:</strong></li>
<li>0 = Standalone Workstation</li>
<li>1 = Member Workstation</li>
<li>2 = Standalone Server</li>
<li>3 = Member Server</li>
<li>4 = Backup Domain Controller</li>
<li>5 = Primary Domain Controller</li>
</ul>
<h4 id="current-time-zone">Current Time Zone</h4>
<ul>
<li><strong>Description:</strong> System timezone setting</li>
<li><strong>Remote:</strong> <code>(Get-TimeZone).Id</code></li>
<li><strong>Local:</strong> <code>(Get-TimeZone).Id</code></li>
<li><strong>API Parameter:</strong> <code>currentTimeZone</code></li>
<li><strong>Example:</strong> <code>Eastern Standard Time</code></li>
</ul>
<h4 id="pc-type">PC Type</h4>
<ul>
<li><strong>Description:</strong> Classification based on installed software</li>
<li><strong>Remote:</strong> Detection function in scriptblock</li>
<li><strong>Local:</strong> <code>Get-PCType</code> function</li>
<li><strong>API Parameter:</strong> <code>pcType</code></li>
<li><strong>Values:</strong> Dashboard, Lobby Display, CMM, Wax Trace, Keyence, EAS1000, Genspect, Heat Treat, Inspection, Shopfloor, Engineer, Standard</li>
</ul>
<hr>
<h3 id="dnc-configuration">DNC Configuration</h3>
<h4 id="dnc-general-settings">DNC General Settings</h4>
<ul>
<li><strong>Description:</strong> Machine DNC settings from GE Aircraft Engines registry</li>
<li><strong>Remote:</strong> Read from <code>HKLM:\SOFTWARE\[WOW6432Node\]GE Aircraft Engines\DNC\General</code></li>
<li><strong>Local:</strong> Read from same registry path via <code>Get-DNCConfig</code></li>
<li><strong>API Parameter:</strong> <code>dncConfig</code> (JSON object)</li>
</ul>
<p><strong>DNC Config Fields:</strong></p>
<table>
<thead><tr>
<th>Field</th>
<th>Registry Key</th>
<th>API Key</th>
</tr></thead>
<tbody>
<tr>
<td>Site</td>
<td>Site</td>
<td>dncConfig.Site</td>
</tr>
<tr>
<td>CNC</td>
<td>Cnc</td>
<td>dncConfig.CNC</td>
</tr>
<tr>
<td>NcIF</td>
<td>NcIF</td>
<td>dncConfig.NcIF</td>
</tr>
<tr>
<td>Machine No</td>
<td>MachineNo</td>
<td>dncConfig.MachineNo</td>
</tr>
<tr>
<td>Host Type</td>
<td>HostType</td>
<td>dncConfig.HostType</td>
</tr>
<tr>
<td>FTP Primary</td>
<td>FtpHostPrimary</td>
<td>dncConfig.FtpHostPrimary</td>
</tr>
<tr>
<td>FTP Secondary</td>
<td>FtpHostSecondary</td>
<td>dncConfig.FtpHostSecondary</td>
</tr>
</tbody></table>
<hr>
<h3 id="ge-registry-information">GE Registry Information</h3>
<h4 id="registry-presence">Registry Presence</h4>
<ul>
<li><strong>Description:</strong> Whether GE Aircraft Engines registry exists</li>
<li><strong>32-bit Path:</strong> <code>HKLM:\SOFTWARE\GE Aircraft Engines</code></li>
<li><strong>64-bit Path:</strong> <code>HKLM:\SOFTWARE\WOW6432Node\GE Aircraft Engines</code></li>
<li><strong>API Parameters:</strong></li>
<li><code>dncGeRegistry32Bit</code> (1 or 0)</li>
<li><code>dncGeRegistry64Bit</code> (1 or 0)</li>
</ul>
<h4 id="dual-path-configuration">Dual Path Configuration</h4>
<ul>
<li><strong>Description:</strong> eFocas dual-path settings for redundant machine connections</li>
<li><strong>Registry Path:</strong> <code>...\DNC\eFocas</code></li>
<li><strong>API Parameters:</strong></li>
<li><code>dncDualPathEnabled</code> (1, 0, or null)</li>
<li><code>dncPath1Name</code> (string)</li>
<li><code>dncPath2Name</code> (string)</li>
</ul>
<hr>
<h3 id="network-interfaces">Network Interfaces</h3>
<p>Both scripts collect all active network interfaces with these fields:</p>
<table>
<thead><tr>
<th>Field</th>
<th>Description</th>
<th>API Key</th>
</tr></thead>
<tbody>
<tr>
<td>InterfaceName</td>
<td>Adapter name</td>
<td>interfaceName</td>
</tr>
<tr>
<td>IPAddress</td>
<td>IPv4 address</td>
<td>ipAddress</td>
</tr>
<tr>
<td>SubnetMask</td>
<td>CIDR prefix length</td>
<td>subnetMask</td>
</tr>
<tr>
<td>DefaultGateway</td>
<td>Gateway address</td>
<td>defaultGateway</td>
</tr>
<tr>
<td>MACAddress</td>
<td>Physical address</td>
<td>macAddress</td>
</tr>
<tr>
<td>IsDHCP</td>
<td>DHCP enabled</td>
<td>isDhcp</td>
</tr>
<tr>
<td>IsActive</td>
<td>Interface is up</td>
<td>isActive</td>
</tr>
<tr>
<td>IsMachineNetwork</td>
<td>192.168.<em>.</em> or 100.0.0.* address</td>
<td>isMachineNetwork</td>
</tr>
<tr>
<td>IsPrimary</td>
<td>10.134.<em>.</em> address</td>
<td>isPrimary</td>
</tr>
</tbody></table>
<p><strong>Network Classification:</strong></p>
<ul>
<li><strong>IsPrimary = 1:</strong> IP matches <code>^10\.134\.</code> (corporate network)</li>
<li><strong>IsMachineNetwork = 1:</strong> IP matches <code>^192\.168\.</code> or <code>^100\.0\.0\.</code> (machine network, includes CMM cases)</li>
</ul>
<hr>
<h3 id="application-detection">Application Detection</h3>
<h4 id="serial-ports">Serial Ports</h4>
<ul>
<li><strong>Description:</strong> List of COM ports for DNC communication</li>
<li><strong>Collection:</strong> <code>Get-CimInstance -ClassName Win32_SerialPort</code></li>
<li><strong>API Parameter:</strong> <code>serialPorts</code> (JSON array)</li>
<li><strong>Example:</strong></li>
</ul>
<pre><code class="language-json"> [
{&quot;PortName&quot;: &quot;COM1&quot;, &quot;Description&quot;: &quot;Communications Port&quot;},
{&quot;PortName&quot;: &quot;COM3&quot;, &quot;Description&quot;: &quot;USB Serial Port&quot;}
]</code></pre>
<h4 id="vnc-detection">VNC Detection</h4>
<ul>
<li><strong>Description:</strong> Whether VNC Server is installed</li>
<li><strong>Collection Methods:</strong></li>
</ul>
<ol>
<li>Registry check for VNC Server/Connect/RealVNC in Uninstall keys</li>
<li>Service check for <code>vncserver*</code> services</li>
</ol>
<ul>
<li><strong>API Parameter:</strong> <code>hasVnc</code> (1 or 0)</li>
</ul>
<h4 id="all-installed-applications">All Installed Applications</h4>
<ul>
<li><strong>Description:</strong> Complete list of installed software</li>
<li><strong>Collection Locations:</strong></li>
<li><code>HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*</code></li>
<li><code>HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*</code></li>
<li><code>HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*</code></li>
<li><code>Registry::HKU\&lt;SID&gt;\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*</code></li>
<li><strong>API Parameters:</strong></li>
<li><code>allInstalledApps</code> (pipe-delimited string)</li>
<li><code>allInstalledAppsCount</code> (integer)</li>
</ul>
<h4 id="tracked-applications">Tracked Applications</h4>
<ul>
<li><strong>Description:</strong> Applications matched against <code>applications.csv</code></li>
<li><strong>API Parameter:</strong> <code>installedApplications</code> (JSON array)</li>
<li><strong>Example:</strong></li>
</ul>
<pre><code class="language-json"> [
{&quot;appid&quot;: 2, &quot;appname&quot;: &quot;UDC&quot;, &quot;version&quot;: &quot;2.1.0&quot;, &quot;isactive&quot;: 1},
{&quot;appid&quot;: 15, &quot;appname&quot;: &quot;Tanium&quot;, &quot;version&quot;: &quot;7.4.2&quot;, &quot;isactive&quot;: 1}
]</code></pre>
<hr>
<h3 id="printer-information">Printer Information</h3>
<h4 id="default-printer-fqdn">Default Printer FQDN</h4>
<ul>
<li><strong>Description:</strong> Network printer port name (IP or FQDN)</li>
<li><strong>Collection:</strong> <code>Get-WmiObject -Query &quot;SELECT * FROM Win32_Printer WHERE Default=$true&quot;</code></li>
<li><strong>Filtering:</strong> Excludes local/virtual printers (USB, LPT, XPS, PDF, etc.)</li>
<li><strong>Processing:</strong> Strips trailing underscore and port suffix (e.g., <code>10.80.92.53_2</code><code>10.80.92.53</code>)</li>
<li><strong>API Parameter:</strong> <code>defaultPrinterFQDN</code></li>
</ul>
<hr>
<h2 id="collection-methods">Collection Methods</h2>
<h3 id="remote-script-data-flow">Remote Script Data Flow</h3>
<pre><code>Admin Workstation Target PC
│ │
│ Invoke-Command (WinRM) │
├───────────────────────────────→│
│ │ ┌─────────────────────┐
│ │ │ Collect data: │
│ │ │ - CIM instances │
│ │ │ - Registry │
│ │ │ - Processes │
│ │ │ - Network config │
│ │ └─────────────────────┘
│ │
│ Return $result hashtable │
│←───────────────────────────────┤
│ │
│ ┌──────────────────────────┐ │
│ │ Send-PCDataToApi │ │
│ │ POST to ShopDB API │ │
│ └──────────────────────────┘ │
│ │
│ HTTP POST to API │
├───────────────────────────────→│ ShopDB Server</code></pre>
<h3 id="local-script-data-flow">Local Script Data Flow</h3>
<pre><code>Target PC
│ ┌────────────────────────────────┐
│ │ Collect-SystemInfo │
│ │ - CIM instances │
│ │ - Registry │
│ │ - Processes │
│ └────────────────────────────────┘
│ ┌────────────────────────────────┐
│ │ Get-ShopfloorConfigurations │
│ │ - Network interfaces │
│ │ - DNC config │
│ │ - GE Registry │
│ └────────────────────────────────┘
│ ┌────────────────────────────────┐
│ │ Send-CompleteDataToDashboard │
│ │ POST to ShopDB API │
│ └────────────────────────────────┘
│ HTTP POST to API
├───────────────────────────────────→ ShopDB Server</code></pre>
<hr>
<h2 id="api-parameter-mapping">API Parameter Mapping</h2>
<h3 id="updatecompleteasset-action">updateCompleteAsset Action</h3>
<table>
<thead><tr>
<th>Category</th>
<th>API Parameter</th>
<th>Remote Source</th>
<th>Local Source</th>
</tr></thead>
<tbody>
<tr>
<td><strong>Basic</strong></td>
<td>hostname</td>
<td>$result.Hostname</td>
<td>$systemInfo.Hostname</td>
</tr>
<tr>
<td></td>
<td>serialNumber</td>
<td>$result.SerialNumber</td>
<td>$systemInfo.SerialNumber</td>
</tr>
<tr>
<td></td>
<td>serviceTag</td>
<td>$result.ServiceTag</td>
<td>$systemInfo.ServiceTag</td>
</tr>
<tr>
<td></td>
<td>manufacturer</td>
<td>$result.Manufacturer</td>
<td>$systemInfo.Manufacturer</td>
</tr>
<tr>
<td></td>
<td>model</td>
<td>$result.Model</td>
<td>$systemInfo.Model</td>
</tr>
<tr>
<td></td>
<td>pcType</td>
<td>$result.PCType</td>
<td>$systemInfo.PCType</td>
</tr>
<tr>
<td></td>
<td>loggedInUser</td>
<td>$result.LoggedInUser</td>
<td>$systemInfo.LoggedInUser</td>
</tr>
<tr>
<td></td>
<td>machineNo</td>
<td>$result.MachineNo</td>
<td>$systemInfo.MachineNo</td>
</tr>
<tr>
<td></td>
<td>osVersion</td>
<td>$result.OSVersion</td>
<td>$systemInfo.OSVersion</td>
</tr>
<tr>
<td></td>
<td>lastBootUpTime</td>
<td>$result.LastBootUpTime</td>
<td>$systemInfo.LastBootUpTime</td>
</tr>
<tr>
<td></td>
<td>totalPhysicalMemory</td>
<td>$result.TotalPhysicalMemory</td>
<td>$systemInfo.TotalPhysicalMemory</td>
</tr>
<tr>
<td></td>
<td>domainRole</td>
<td>$result.DomainRole</td>
<td>$systemInfo.DomainRole</td>
</tr>
<tr>
<td></td>
<td>currentTimeZone</td>
<td>$result.CurrentTimeZone</td>
<td>$systemInfo.CurrentTimeZone</td>
</tr>
<tr>
<td><strong>VNC</strong></td>
<td>hasVnc</td>
<td>$result.HasVnc</td>
<td>$systemInfo.HasVnc</td>
</tr>
<tr>
<td><strong>Serial</strong></td>
<td>serialPorts</td>
<td>$result.SerialPorts (JSON)</td>
<td>$systemInfo.SerialPorts (JSON)</td>
</tr>
<tr>
<td><strong>Apps</strong></td>
<td>allInstalledApps</td>
<td>$result.AllInstalledApps</td>
<td>$systemInfo.AllInstalledApps</td>
</tr>
<tr>
<td></td>
<td>allInstalledAppsCount</td>
<td>$result.AllInstalledAppsCount</td>
<td>$systemInfo.AllInstalledAppsCount</td>
</tr>
<tr>
<td><strong>Printer</strong></td>
<td>defaultPrinterFQDN</td>
<td>$result.DefaultPrinterFQDN</td>
<td>Get-DefaultPrinterFQDN</td>
</tr>
<tr>
<td><strong>Network</strong></td>
<td>networkInterfaces</td>
<td>$result.NetworkInterfaces (JSON)</td>
<td>$shopfloorInfo.NetworkInterfaces (JSON)</td>
</tr>
<tr>
<td><strong>Comm</strong></td>
<td>commConfigs</td>
<td>$result.CommConfigs (JSON)</td>
<td>$shopfloorInfo.CommConfigs (JSON)</td>
</tr>
<tr>
<td><strong>DNC</strong></td>
<td>dncConfig</td>
<td>$result.DNCConfig (JSON)</td>
<td>$shopfloorInfo.DNCConfig (JSON)</td>
</tr>
<tr>
<td></td>
<td>dncGeRegistry32Bit</td>
<td>$result.GERegistryInfo.Registry32Bit</td>
<td>$shopfloorInfo.GERegistryInfo.Registry32Bit</td>
</tr>
<tr>
<td></td>
<td>dncGeRegistry64Bit</td>
<td>$result.GERegistryInfo.Registry64Bit</td>
<td>$shopfloorInfo.GERegistryInfo.Registry64Bit</td>
</tr>
<tr>
<td></td>
<td>dncDualPathEnabled</td>
<td>$result.GERegistryInfo.DualPathEnabled</td>
<td>$shopfloorInfo.GERegistryInfo.DualPathEnabled</td>
</tr>
<tr>
<td></td>
<td>dncPath1Name</td>
<td>$result.GERegistryInfo.Path1Name</td>
<td>$shopfloorInfo.GERegistryInfo.Path1Name</td>
</tr>
<tr>
<td></td>
<td>dncPath2Name</td>
<td>$result.GERegistryInfo.Path2Name</td>
<td>$shopfloorInfo.GERegistryInfo.Path2Name</td>
</tr>
</tbody></table>
<hr>
<h2 id="testing-parity">Testing Parity</h2>
<h3 id="manual-parity-test">Manual Parity Test</h3>
<p>Run both scripts on the same PC and compare results:</p>
<p><strong>Step 1: Run Local Script</strong></p>
<pre><code class="language-powershell"># On target PC
.\Update-PC-CompleteAsset.ps1 -DashboardURL &quot;http://dev-server/api.asp&quot; &gt; local-output.txt</code></pre>
<p><strong>Step 2: Run Remote Script</strong></p>
<pre><code class="language-powershell"># From admin workstation
.\Update-ShopfloorPCs-Remote.ps1 -ComputerName &quot;TARGET-PC&quot; -ApiUrl &quot;http://dev-server/api.asp&quot; &gt; remote-output.txt</code></pre>
<p><strong>Step 3: Compare Database Records</strong></p>
<pre><code class="language-sql">-- Check if both created/updated the same record
SELECT * FROM machines WHERE hostname = &#x27;TARGET-PC&#x27; ORDER BY lastupdated DESC LIMIT 2;
-- Compare specific fields
SELECT hostname, serialnumber, pctype, totalphysicalmemory, domainrole
FROM machines WHERE hostname = &#x27;TARGET-PC&#x27;;</code></pre>
<h3 id="automated-parity-check-script">Automated Parity Check Script</h3>
<pre><code class="language-powershell"># parity-test.ps1
param(
[Parameter(Mandatory)]
[string]$ComputerName,
[PSCredential]$Credential
)
# Run remote collection
$remoteData = .\Update-ShopfloorPCs-Remote.ps1 -ComputerName $ComputerName -Credential $Credential -WhatIf
# Fields to compare
$fields = @(
&#x27;Hostname&#x27;, &#x27;SerialNumber&#x27;, &#x27;ServiceTag&#x27;, &#x27;Manufacturer&#x27;, &#x27;Model&#x27;,
&#x27;TotalPhysicalMemory&#x27;, &#x27;DomainRole&#x27;, &#x27;CurrentTimeZone&#x27;, &#x27;PCType&#x27;,
&#x27;HasVnc&#x27;, &#x27;AllInstalledAppsCount&#x27;
)
# Output comparison
foreach ($field in $fields) {
Write-Host &quot;$field : $($remoteData.$field)&quot;
}</code></pre>
<hr>
<h2 id="known-differences">Known Differences</h2>
<h3 id="local-only-fields">Local-Only Fields</h3>
<p>These fields can only be collected by the local script:</p>
<table>
<thead><tr>
<th>Field</th>
<th>Reason</th>
</tr></thead>
<tbody>
<tr>
<td>V-Drive Access</td>
<td>Requires user's mapped network drives</td>
</tr>
<tr>
<td>C:\Apps Folder Access</td>
<td>Network permissions differ in WinRM context</td>
</tr>
</tbody></table>
<h3 id="context-differences">Context Differences</h3>
<table>
<thead><tr>
<th>Aspect</th>
<th>Remote</th>
<th>Local</th>
</tr></thead>
<tbody>
<tr>
<td>User context</td>
<td>SYSTEM (via WinRM)</td>
<td>Logged-in user or SYSTEM</td>
</tr>
<tr>
<td>Network drives</td>
<td>Not accessible</td>
<td>Accessible</td>
</tr>
<tr>
<td>User registry (HKCU)</td>
<td>SYSTEM's HKCU</td>
<td>User's HKCU</td>
</tr>
<tr>
<td>Per-user apps</td>
<td>Via HKU enumeration</td>
<td>Via HKU + HKCU</td>
</tr>
</tbody></table>
<h3 id="pc-type-detection">PC Type Detection</h3>
<p>Both scripts use the same detection priority:</p>
<ol>
<li>Dashboard (GE Aerospace Dashboard)</li>
<li>Lobby Display (GE Aerospace Lobby Display)</li>
<li>CMM (PC-DMIS, goCMM, DODA)</li>
<li>Wax Trace (FormTracePak, FormStatusMonitor)</li>
<li>Keyence (VR-3000/5000/6000)</li>
<li>EAS1000 (GageCal, NI Software)</li>
<li>Genspect</li>
<li>Heat Treat</li>
<li>Inspection (machine number based)</li>
<li>Shopfloor (default for domain shop PCs)</li>
</ol>
<p><strong>Additional local-only types:</strong></p>
<ul>
<li>Engineer (requires V-Drive AND C:\Apps)</li>
<li>Standard (default)</li>
</ul>
</body>
</html>