From 5f39e796736b24c6cc03c90339db96f30a316bd3 Mon Sep 17 00:00:00 2001 From: fadwen <110697945+fadwen@users.noreply.github.com> Date: Thu, 8 Oct 2026 13:19:42 -0700 Subject: [PATCH] fix(harness): start child processes without NoDefaultCurrentDirectoryInExePath With NoDefaultCurrentDirectoryInExePath set in the caller's environment, a per-user shell setting, cmd.exe does not look in its working folder, so a Win32 install command given as a bare batch file ("install.cmd") failed with "'install.cmd' is not recognized" from Invoke-IntuneWin32AppTest. The agent's cmd.exe runs without the caller's profile and finds the file. The launcher now removes the variable from the direct child's environment, next to the PSModulePath handling that already edits it. The scheduled-task modes run under another account's environment and are unchanged. --- CHANGELOG.md | 8 +++++++- Private/Invoke-IslProcess.ps1 | 4 ++++ .../Unit/Private/Invoke-IslProcess.Tests.ps1 | 20 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91b12a4..5eec5de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,13 @@ release notes. ## [Unreleased] -Nothing yet. +### Fixed + +- A Win32 install or uninstall command named as a bare batch file (`install.cmd`) failed with + "'install.cmd' is not recognized" from `Invoke-IntuneWin32AppTest` on a machine where + `NoDefaultCurrentDirectoryInExePath` is set in the caller's environment, a per-user shell + setting that stops `cmd.exe` looking in its working folder. The agent's `cmd.exe` runs without + the caller's profile, so the harness now starts its child processes without the variable. ## [0.29.0] - 2026-10-07 diff --git a/Private/Invoke-IslProcess.ps1 b/Private/Invoke-IslProcess.ps1 index 7e4d3ba..fe35063 100644 --- a/Private/Invoke-IslProcess.ps1 +++ b/Private/Invoke-IslProcess.ps1 @@ -85,6 +85,10 @@ if ($desktopModulePath) { $startInfo.Environment['PSModulePath'] = $desktopModulePath } else { $null = $startInfo.Environment.Remove('PSModulePath') } } + # With NoDefaultCurrentDirectoryInExePath set in the caller's own environment, cmd.exe does + # not look in its working folder, and a bare 'install.cmd' fails with "not recognized". The + # agent's cmd.exe runs without the caller's profile, so the child runs without the setting + $null = $startInfo.Environment.Remove('NoDefaultCurrentDirectoryInExePath') $process = [System.Diagnostics.Process]::new() $process.StartInfo = $startInfo diff --git a/Tests/Unit/Private/Invoke-IslProcess.Tests.ps1 b/Tests/Unit/Private/Invoke-IslProcess.Tests.ps1 index 3a222f8..0fb04ee 100644 --- a/Tests/Unit/Private/Invoke-IslProcess.Tests.ps1 +++ b/Tests/Unit/Private/Invoke-IslProcess.Tests.ps1 @@ -47,6 +47,26 @@ Describe 'Invoke-IslProcess' -Tag 'Unit', 'Private' { $result.StdOut.Trim() | Should-Be $TestDrive } + It 'lets cmd.exe find a batch file in the working folder whatever the caller''s own shell setting' { + # NoDefaultCurrentDirectoryInExePath in the caller's environment stops cmd.exe looking in + # the working folder; the agent's cmd.exe has no such setting, so the child must not either + Set-Content -Path (Join-Path $TestDrive 'install.cmd') -Value '@echo ran' -Encoding ascii + $saved = $env:NoDefaultCurrentDirectoryInExePath + $env:NoDefaultCurrentDirectoryInExePath = '1' + try { + $result = Invoke-Process @{ + FilePath = $script:Cmd; Arguments = '/C "install.cmd"' + WorkingDirectory = $TestDrive; WorkFolder = $TestDrive + } + } + finally { + $env:NoDefaultCurrentDirectoryInExePath = $saved + } + $result.ExitCode | Should-Be 0 + $result.StdOut.Trim() | Should-Be 'ran' + $result.StdErr.Trim() | Should-Be '' + } + It 'closes stdin so a read returns instead of waiting' { $result = Invoke-Process @{ FilePath = $script:Cmd; Arguments = '/C set /p answer=name? & echo [%answer%]'