Install-ScriptWorkerIsolation.ps1 fails on Windows (PowerShell 7: no DirectoryInfo.GetAccessControl; 5.1: StrictMode .Count on scalar) and -Uninstall fails too #883
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by the #800 Windows service gate on windev, 2026-11-12. This was the first real run of the #780 installer: master
438484fd, self-contained win-x64 Host installed as theOtOpcUaHostservice underNT SERVICE\OtOpcUaHost. Its dry-run harness (Test-ScriptWorkerIsolation.ps1) only asserts the plan data, so neither defect below was caught.Install-ScriptWorkerIsolation.ps1fails on both PowerShell hosts. Its documented rollback (-Uninstall) fails too.-WhatIflists all 7 steps and changes nothing.OtOpcUaScriptWorkerand the PE-cache directory, then stops at the PeCacheDir ACL withMethod invocation failed because [System.IO.DirectoryInfo] does not contain a method named 'GetAccessControl'.DirectoryInfo.GetAccessControl()/SetAccessControl()are .NET Framework instance methods; on .NET they live inSystem.IO.FileSystemAclExtensions. The code isScriptWorkerIsolation.psm1Set-OtOpcUaExplicitAce(line 192) and thePeCacheDirstep (line 256).PeEntriesDirwithThe property 'Count' cannot be found on this object(PropertyNotFoundStrict).$wanted = if ($Remove) { @() } else { , [FileSystemAccessRule]::new(...) }. Anifused as an expression unrolls its output, so$wantedis a single rule, or$nullon-Remove..Counton that throws underSet-StrictMode -Version Latestin 5.1.-Uninstall(the rollback in docs/ServiceHosting.md and #794) fails the same way on 5.1, at its first ACE step after HostServiceEnv/FirewallBlockOutbound. So a partial install cannot be rolled back with the tool.Patch, validated on windev: use
Get-Acl/Set-Aclinstead of the instance methods, and wrap the rule in@(if (-not $Remove) { ... }).With this patch the #800 run passed every step:
unchanged;-Uninstallunder 5.1, then again under pwsh, with all stepsunchanged.Details are on #800. Fix the repo copy and add a Windows-executed test of apply → re-apply → uninstall. The plan-only harness cannot see these.
This blocks #794 (QA gate) as written: step 3 "apply, then run again" fails.
Fixed and verified on windev, master
88e53f7f(evidence1172687d). Install, re-apply and-Uninstallnow work on both PowerShell 7.6 and Windows PowerShell 5.1.What changed in
scripts/install/ScriptWorkerIsolation.psm1:Get-Acl/Set-Aclreplace theDirectoryInfoinstance methods, and$wanted = @(if (...) { ... })keeps the rule an array.sc.exe ... binPath= "\"C:\...exe\""with legacy quoting, so the anchor path was stored unquoted, andAnchorServicereportedchangedon every re-run (a path with spaces, likeC:\Program Files\OtOpcUa, is worse).sc.exe create|confignow goes throughInvoke-OtOpcUaScwith an explicit command line, so both hosts store the same quoted path.Verification:
scripts/install/tests/Test-ScriptWorkerIsolation.Windows.ps1(dry run, apply, re-apply, uninstall, uninstall; scratch worker/host-service names; refuses to run where the real isolation is installed). On windev with the final script: 24/24 on 5.1 and 24/24 on pwsh 7. Before the third fix it failed on 5.1 at the re-apply.OtOpcUaHostservice, repo script, no patch, four cycles (apply host / second host): pwsh/5.1, 5.1/pwsh (before the third fix: AnchorServicechangedon re-apply), 5.1/pwsh (final), pwsh/5.1 (final). With the final script every re-apply reported 7/7unchangedand the second uninstall 6/6unchanged;-WhatIfchanged nothing on either host.script-runnerHealthy, strict-peer/API-key matrix green. See RESULTS.md.Invoke-ServiceGate.ps1no longer needs-PatchedIsolation(removed); it gained-ApplyHostand-PrepareFrom candidate.https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi