fix(gwmi): pass -NoProfile -NonInteractive to powershell - #193
Open
Shmuel3 wants to merge 1 commit into
Open
Conversation
The gwmi fallback spawned powershell through the `shell` option, which produces `powershell.exe -c <pipeline>`. Without -NoProfile, every stats poll loads and executes the user's PowerShell profile. That runs arbitrary user startup code on each poll, adds the profile's startup cost to every call, and fails the poll outright when a profile writes to stderr (bin.js treats any stderr output as a fatal error). Profiles that block also leave the spawned powershell hanging forever, so polling apps accumulate orphaned processes. Spawn powershell.exe directly with -NoProfile -NonInteractive and pass the pipeline as a single -Command argument. The query, property list and format-table output are unchanged, so the parser is untouched.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
lib/gwmi.jsspawns PowerShell through Node'sshelloption, which Node turns intopowershell.exe -c <pipeline>. Neither-NoProfilenor-NonInteractiveis passed, so every stats poll loads and executes the user's PowerShell profile: arbitrary user startup code on every poll, the profile's startup cost added to every call, a failed poll whenever the profile writes to stderr (lib/bin.jstreats non-empty stderr as fatal), and a permanently hung poll plus a leaked powershell whenever the profile blocks.Full write-up, including a real incident where the leak exhausted Windows socket buffer space, is in #192. Same class of failure as the 4.0.1 fix ("fix spawned wmic processes not exiting … leading to infinite build up").
Worth noting from #192: because
spawn('wmic', function (err) { ... })inlib/stats.jsthrowsERR_INVALID_ARG_TYPEsynchronously on every platform, thecatchalways fires and gwmi is always the Windows backend on 4.x — so this path affects every Windows user, not only machines missingwmic. I've left that alone to keep this PR to one concern.Fix
Spawn
powershell.exedirectly with explicit flags, passing the pipeline as a single-Commandargument.format-tableoutput are unchanged, so the parser below the spawn is untouched.windowsVerbatimArgumentslets Node quote the-Commandargument. It contains spaces and|, but no double quotes or backslashes, so it is wrapped in"…"and PowerShell receives exactly one command string. pids are alreadyparseInt-validated instats.jsbefore reaching here, so nothing user-controlled can introduce a quote.-ExecutionPolicy Bypassis deliberately not added: execution policy applies to script files, not-Command.Tests
Added a unit test asserting the spawn target and that
-NoProfile/-NonInteractiveare passed, mirroring the existing gwmi/wmic mock style. It is declaredtest.serialso it cannot race the existing test over the sharedmockeryand history state.What I verified, and what I couldn't
npm testpasses (17 tests) on macOS.test-windowsjob covers that path, and per the note aboveintegration.json Windows goes through gwmi.npm run lintreports one error,lib/stats.js:64:14: Extra semicolon. It is pre-existing onmain(from 36383b8), not introduced here, and in a file this PR deliberately doesn't touch. Happy to fold the one-character fix in if you'd rather the lint job go green.