From 30ad9f62a481694b708ae7bab9a7f4ac55f8cc78 Mon Sep 17 00:00:00 2001 From: Matt Lindell Date: Sat, 4 Apr 2026 13:00:01 -0700 Subject: [PATCH 1/3] Add -NoProfile to elevated Run-Command subprocess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The elevated powershell.exe process spawned by Run-Command loads the user's profile, which can cause hangs when the profile contains interactive commands (e.g. a PS5→PS7 redirect guard). Adding -NoProfile skips profile loading, which is correct for a utility subprocess that only runs a single command. --- src/functions/helpers.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/helpers.ps1 b/src/functions/helpers.ps1 index 7836d91..f679593 100644 --- a/src/functions/helpers.ps1 +++ b/src/functions/helpers.ps1 @@ -212,7 +212,7 @@ function Make-Symbolic-Link { function Run-Command { param($command) - $process = Start-Process powershell -ArgumentList "-ExecutionPolicy Bypass -Command `"$command`"" -Verb RunAs -WindowStyle Hidden -PassThru -Wait + $process = Start-Process powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"$command`"" -Verb RunAs -WindowStyle Hidden -PassThru -Wait $process.WaitForExit() return $process.ExitCode } From 5a31a548c2c4a0ee33bd3122142a654736c6032d Mon Sep 17 00:00:00 2001 From: Matt Lindell Date: Sat, 4 Apr 2026 13:09:09 -0700 Subject: [PATCH 2/3] Add test for Run-Command -NoProfile flag Verifies that Run-Command passes -NoProfile to the elevated powershell.exe subprocess, preventing user profiles from interfering with the command execution. --- tests/helpers.tests.ps1 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/helpers.tests.ps1 b/tests/helpers.tests.ps1 index 7ede0b6..00b6868 100644 --- a/tests/helpers.tests.ps1 +++ b/tests/helpers.tests.ps1 @@ -1350,3 +1350,23 @@ Describe "Get-BinaryArchitecture-From-DLL" { } } } + +Describe "Run-Command" { + BeforeAll { + . "$PSScriptRoot\..\src\functions\helpers.ps1" + } + + Context "When executing elevated commands" { + It "Passes -NoProfile to prevent user profile from loading" { + $mockProcess = [PSCustomObject]@{ ExitCode = 0 } + $mockProcess | Add-Member -MemberType ScriptMethod -Name WaitForExit -Value {} + Mock Start-Process { return $mockProcess } + + $result = Run-Command -command "echo test" + + Should -Invoke Start-Process -Times 1 -ParameterFilter { + $ArgumentList -like "*-NoProfile*" + } + } + } +} From c0eba12e5d1d3421c6e332b412bce90c7a7bde4d Mon Sep 17 00:00:00 2001 From: Matt Lindell Date: Fri, 17 Apr 2026 16:27:47 -0700 Subject: [PATCH 3/3] Address PR feedback: drop redundant import, add -NoProfile to pvm.bat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove helpers.ps1 dot-source from Run-Command test — pvm.ps1 loads it when running `pvm test`. Mirror Run-Command's -NoProfile fix in pvm.bat so the top-level launcher also skips profile load. --- pvm.bat | 4 ++-- tests/helpers.tests.ps1 | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/pvm.bat b/pvm.bat index f55c13d..813c603 100644 --- a/pvm.bat +++ b/pvm.bat @@ -10,9 +10,9 @@ set "ARGS=%ARGS:-- =%" where pwsh >nul 2>&1 if %ERRORLEVEL%==0 ( - pwsh -ExecutionPolicy Bypass -File "%FILE_TARGET%" %ARGS% + pwsh -NoProfile -ExecutionPolicy Bypass -File "%FILE_TARGET%" %ARGS% ) else ( - powershell -ExecutionPolicy Bypass -File "%FILE_TARGET%" %ARGS% + powershell -NoProfile -ExecutionPolicy Bypass -File "%FILE_TARGET%" %ARGS% ) endlocal diff --git a/tests/helpers.tests.ps1 b/tests/helpers.tests.ps1 index 00b6868..d15412c 100644 --- a/tests/helpers.tests.ps1 +++ b/tests/helpers.tests.ps1 @@ -1352,10 +1352,6 @@ Describe "Get-BinaryArchitecture-From-DLL" { } Describe "Run-Command" { - BeforeAll { - . "$PSScriptRoot\..\src\functions\helpers.ps1" - } - Context "When executing elevated commands" { It "Passes -NoProfile to prevent user profile from loading" { $mockProcess = [PSCustomObject]@{ ExitCode = 0 }