Export-FormtracepakInventory: drop Get-Service entirely (SCM hang)

WJF00052 / WJF00083 / WJF00084 / WJF00159 hung indefinitely on step [5/5]
during the 2026-05-24 capture pass and the operator killed the .bat,
leaving empty inventory CSVs. The earlier Start-Job + Wait-Job -Timeout 30
guard (commit fce6680) was insufficient: Stop-Job on a Get-Service that's
blocked on a degraded Service Control Manager can itself block in the SCM
call (Sentinel HASP driver service in particular has been observed to
wedge Get-Service for minutes), so the main script never unblocked even
after the 30s timeout fired.

Service state isn't load-bearing for identifying the install on a bay
(version + model + DeviceName come from disk + registry, not the SCM),
so the cleanest fix is to drop the Get-Service block entirely. Get-Process
is fast and stays. Step [5/5] label changed from "Checking running
processes and services" to "Checking running processes".

Smoke tested on win11 VM: full Export against a real v6.213 / AVANT
install completes in ~25 s (was 2.9 s with no install, 25 s now reflects
the legitimate ~95k registry walk that dominates the runtime - not the
service hang).
This commit is contained in:
cproudlock
2026-05-24 11:03:20 -04:00
parent cb149ed8cd
commit d359563a4c

View File

@@ -291,8 +291,20 @@ foreach ($uPath in $uninstallPaths) {
} }
} }
# ---------------------------------------------------------------------- 5. Locate Running Processes / Services ---------------------------------------------------------------------- # ---------------------------------------------------------------------- 5. Locate Running Processes ----------------------------------------------------------------------
Write-Host "[5/5] Checking running processes and services..." -ForegroundColor Cyan #
# Service enumeration was removed 2026-05-24. Get-Service was hanging
# indefinitely on West Jefferson wax/trace bays (WJF00052, WJF00083,
# WJF00084, WJF00159 were left with empty inventory CSVs because the
# operator killed the .bat after the apparent hang). The earlier
# Start-Job + Wait-Job -Timeout 30 fence was insufficient: Stop-Job on
# a Get-Service that's blocked on the Service Control Manager can itself
# block in the SCM call, so the main script never unblocked after the
# timeout fired. Service state is audit-nice-to-have, not load-bearing
# for identifying the install (version + model + DeviceName come from
# elsewhere), so the cleanest fix is to drop it entirely. Get-Process is
# fast and stays.
Write-Host "[5/5] Checking running processes..." -ForegroundColor Cyan
$processPatterns = @('Formpak', 'Formtracepak', 'SurfPak', 'MtSurf', 'MtForm', 'Mitutoyo') $processPatterns = @('Formpak', 'Formtracepak', 'SurfPak', 'MtSurf', 'MtForm', 'Mitutoyo')
foreach ($pp in $processPatterns) { foreach ($pp in $processPatterns) {
@@ -304,38 +316,6 @@ foreach ($pp in $processPatterns) {
} }
} }
# Service enumeration. The original `Get-Service | Where-Object { DisplayName -match ... }`
# materializes every service via the Service Control Manager + post-filters
# in PowerShell and has been observed to hang for minutes on shopfloor PCs
# where the SCM or a single service is in a degraded state (Sentinel HASP
# driver / GE-Enforce agent service have both blocked Get-Service before).
# Replace with -DisplayName server-side wildcard filter (the SCM only
# materializes matching services) and wrap in a 30-second runspace fence so
# any further hang aborts gracefully without taking the whole script down.
$serviceJob = Start-Job -ScriptBlock {
Get-Service -DisplayName 'Mitutoyo*','*FORMTRACEPAK*','*FORMPAK*','*SURFPAK*' -ErrorAction SilentlyContinue |
ForEach-Object {
[PSCustomObject]@{
Name = $_.Name
DisplayName = $_.DisplayName
Status = [string]$_.Status
}
}
}
$services = @()
if (Wait-Job -Job $serviceJob -Timeout 30) {
$services = @(Receive-Job -Job $serviceJob -ErrorAction SilentlyContinue)
} else {
Write-Warning " Service enumeration exceeded 30s timeout - skipping (SCM degraded?)"
Stop-Job -Job $serviceJob -ErrorAction SilentlyContinue
}
Remove-Job -Job $serviceJob -Force -ErrorAction SilentlyContinue
foreach ($svc in $services) {
Add-Item -Category 'Service' -ItemType 'Service' `
-Path $svc.Name -Name $svc.DisplayName `
-Value $svc.Status
}
# ---------------------------------------------------------------------- Output ---------------------------------------------------------------------- # ---------------------------------------------------------------------- Output ----------------------------------------------------------------------
if (-not (Test-Path $OutputPath)) { if (-not (Test-Path $OutputPath)) {