<# pcdmis-probe-debug.ps1 Diagnose "custom probes don't show in PC-DMIS" on a locked-down Win11 bay. RUN AS THE OPERATOR (the account that actually launches PC-DMIS), NOT elevated - the probe search path is a PER-USER registry setting and the UAC VirtualStore is per-user, so we must see THAT account's view. (Machine-wide ProgramData + ACLs are read regardless.) What it reports: 1. Installed PC-DMIS version(s) + install dir (HKLM) 2. The configured Probe Directory / search path (this user's HKCU + every loaded user hive) - where PC-DMIS is actually looking 3. Probe files (*.prb, probe.dat, usrprobe.dat, probebuilder.dat) found under ProgramData, Public Documents, and the install dir 4. ACL on C:\ProgramData\Hexagon\PC-DMIS\ - can the operator WRITE (needed to save/qualify custom probes)? 5. UAC VirtualStore shadow of those paths (probes silently redirected) 6. Version-folder match (probes in a subfolder the running build ignores) Output: C:\Logs\CMM\pcdmis-probe-debug--.txt #> $ErrorActionPreference = 'Continue' $ts = Get-Date -Format 'yyyyMMdd-HHmmss' $dir = 'C:\Logs\CMM' New-Item -ItemType Directory -Path $dir -Force -ErrorAction SilentlyContinue | Out-Null $log = Join-Path $dir "pcdmis-probe-debug-$env:COMPUTERNAME-$ts.txt" function W($m){ $m | Tee-Object -FilePath $log -Append } W "================ PC-DMIS probe debug ================" W "When : $(Get-Date)" W "PC : $env:COMPUTERNAME" W "User : $env:USERDOMAIN\$env:USERNAME (process $([IntPtr]::Size*8)-bit)" $elev = (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) W "Elevated: $elev (run as the OPERATOR, not elevated, for the per-user view)" W "" # ---- 1. Installed PC-DMIS version(s) + install dir ---- W "================ 1. Installed PC-DMIS (HKLM) ================" $instVers = @() foreach ($root in 'HKLM:\SOFTWARE\WOW6432Node\Hexagon\PC-DMIS','HKLM:\SOFTWARE\WOW6432Node\Wai\PC-DMIS','HKLM:\SOFTWARE\Hexagon\PC-DMIS','HKLM:\SOFTWARE\Wai\PC-DMIS') { if (Test-Path $root) { Get-ChildItem $root -ErrorAction SilentlyContinue | ForEach-Object { $v = $_.PSChildName; $instVers += $v $p = (Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue) $exe = $p.Directory; if (-not $exe) { $exe = $p.InstallDir } W (" $root\$v InstallDir=$exe") } } } $instVers = $instVers | Sort-Object -Unique foreach ($d in 'C:\Program Files\Hexagon','C:\Program Files (x86)\Hexagon','C:\Program Files\WAI','C:\Program Files (x86)\WAI') { if (Test-Path $d) { Get-ChildItem $d -Filter 'PC-DMIS*' -Directory -EA SilentlyContinue | ForEach-Object { $exe = Get-ChildItem $_.FullName -Filter 'Pcdlrn.exe' -Recurse -EA SilentlyContinue | Select-Object -First 1 if (-not $exe) { $exe = Get-ChildItem $_.FullName -Filter 'PCDMIS.exe' -Recurse -EA SilentlyContinue | Select-Object -First 1 } if ($exe) { W (" exe: $($exe.FullName) v$((Get-Item $exe.FullName).VersionInfo.FileVersion)") } }} } if (-not $instVers) { W " (no PC-DMIS install keys found under Hexagon/Wai)" } W "" # ---- 2. Probe search path in the registry (this user + all loaded hives) ---- W "================ 2. Probe / search-path registry (per user) ================" W "(values whose name or data mentions probe/search/path/dir - that's where PC-DMIS looks)" New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS -ErrorAction SilentlyContinue | Out-Null $userRoots = @('HKCU:\Software\Hexagon\PC-DMIS','HKCU:\Software\Wai\PC-DMIS') Get-ChildItem 'HKU:\' -ErrorAction SilentlyContinue | Where-Object { $_.PSChildName -match '^S-1-5-21' -and $_.PSChildName -notmatch '_Classes$' } | ForEach-Object { $sid = $_.PSChildName $userRoots += "HKU:\$sid\Software\Hexagon\PC-DMIS" $userRoots += "HKU:\$sid\Software\Wai\PC-DMIS" } foreach ($ur in ($userRoots | Sort-Object -Unique)) { if (-not (Test-Path $ur)) { continue } Get-ChildItem $ur -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $k = $_ $props = Get-ItemProperty $k.PSPath -ErrorAction SilentlyContinue if (-not $props) { return } foreach ($p in $props.PSObject.Properties) { if ($p.Name -like 'PS*') { continue } if ($p.Name -match 'probe|search|path|dir' -or "$($p.Value)" -match 'probe|Hexagon\\PC-DMIS|\\\\') { W (" $($k.PSPath -replace '.*::','')") W (" [$($p.Name)] = $($p.Value)") } } } } W "" # ---- 3. Probe files on disk ---- W "================ 3. Probe files on disk ================" $bases = @( "$env:ProgramData\Hexagon\PC-DMIS", "$env:ProgramData\WAI\PC-DMIS", "$env:PUBLIC\Documents\Hexagon\PC-DMIS", "$env:PUBLIC\Documents\WAI\PC-DMIS", "$env:APPDATA\Hexagon\PC-DMIS", # Roaming per-user "$env:LOCALAPPDATA\Hexagon\PC-DMIS", # Local per-user "$env:APPDATA\WAI\PC-DMIS", "$env:LOCALAPPDATA\WAI\PC-DMIS", "$env:USERPROFILE\Documents\Hexagon\PC-DMIS" ) foreach ($d in 'C:\Program Files\Hexagon','C:\Program Files (x86)\Hexagon') { if (Test-Path $d) { $bases += (Get-ChildItem $d -Filter 'PC-DMIS*' -Directory -EA SilentlyContinue).FullName } } foreach ($b in ($bases | Sort-Object -Unique)) { if (-not (Test-Path $b)) { W " (absent) $b"; continue } W " --- $b ---" Get-ChildItem $b -Recurse -File -Include *.prb,probe.dat,usrprobe.dat,probebuilder.dat -ErrorAction SilentlyContinue | ForEach-Object { W (" {0,10} {1:yyyy-MM-dd} {2}" -f $_.Length, $_.LastWriteTime, $_.FullName) } } W "" # ---- 4. ACL on the ProgramData probe dir (can operator write?) ---- W "================ 4. ProgramData probe-dir ACL (write = save custom probes) ================" $pdRoots = @("$env:ProgramData\Hexagon\PC-DMIS","$env:ProgramData\WAI\PC-DMIS") foreach ($pr in $pdRoots) { if (-not (Test-Path $pr)) { continue } Get-ChildItem $pr -Directory -ErrorAction SilentlyContinue | ForEach-Object { W " --- $($_.FullName) ---" try { (Get-Acl $_.FullName).Access | Where-Object { "$($_.IdentityReference)" -match 'Users|Everyone|Authenticated' } | ForEach-Object { W (" {0,-30} {1,-24} {2}" -f $_.IdentityReference, $_.FileSystemRights, $_.AccessControlType) } } catch { W " Get-Acl failed: $($_.Exception.Message)" } } } W "" # ---- 5. UAC VirtualStore shadow ---- W "================ 5. UAC VirtualStore shadow (probes silently redirected) ================" $vs = "$env:LOCALAPPDATA\VirtualStore" $found = $false foreach ($sub in 'ProgramData\Hexagon\PC-DMIS','Program Files\Hexagon','Program Files (x86)\Hexagon','ProgramData\WAI\PC-DMIS') { $p = Join-Path $vs $sub if (Test-Path $p) { $found = $true Get-ChildItem $p -Recurse -File -Include *.prb,probe.dat,usrprobe.dat,probebuilder.dat -EA SilentlyContinue | ForEach-Object { W (" SHADOW: $($_.FullName)") } } } if (-not $found) { W " (no VirtualStore shadow for $env:USERNAME - good, or PC-DMIS runs under a different account)" } W "" # ---- 6. Version-folder match ---- W "================ 6. Version-folder match ================" W (" installed versions: " + (($instVers -join ', ') | ForEach-Object { if($_){$_}else{'(unknown)'} })) foreach ($b in "$env:ProgramData\Hexagon\PC-DMIS","$env:PUBLIC\Documents\Hexagon\PC-DMIS") { if (Test-Path $b) { W (" data subfolders in $b : " + ((Get-ChildItem $b -Directory -EA SilentlyContinue).Name -join ', ')) } } W " >> if a data subfolder holding your .prb files does NOT match the running build's version, PC-DMIS ignores it." W "" W "================ DONE ================" W "Log: $log" Write-Host "" Write-Host "Collected: $log" -ForegroundColor Green