Create an executable file with PowerShell wildcard characters in its name, say a[hello].ps1, place it somewhere in the PATH, and then try to execute it from PowerShell.
Describe "Execute scripts by file name only via `$env:PATH." {
BeforeAll {
$originalPath= $env:PATH
$dir = Convert-Path TestDrive:
"'hi1'" | Set-Content -LiteralPath $dir/script.ps1
"'hi2'" | Set-Content -LiteralPath $dir/script[1].ps1
$env:PATH += [IO.Path]::PathSeparator + $dir
}
AfterAll {
$env:PATH = $originalPath
}
It "Finds and executes a script with a vanilla file name." {
script.ps1 | Should -Be 'hi1'
}
It "Finds and executes a script whose file name looks like a wildcard." {
script[1].ps1 | Should -Be 'hi2'
}
}
The file executes
It doesn't, but is suggested as a possible similar command.
There is no escaping of the wildcard characters that works.
All version of PowerShell, on Windows 10, specifically 5.1, 6.2.3, and 7.0.0-preview5 were tested.
Because the command contains wildcard characters, it is rejected from a PATH search by CommandSearcher.CanDoPathLookup() in CommandSearcher.setupPathSearcher(). If the command had been in the immediate path, using .\a[hello].ps1 would have successfully worked.
@mklement0, I believe you may have touched on this subject before, but I could not immediately find an existing issue for this.
I believe this can be corrected, by only sending an escaped version of the path to CommandSearcher.CanDoPathLookup(), as I cannot find any reason that the path should not be treated literal at this point. Or, maybe the wildcard character check can be removed entirely, it appears this is the only place where the function CanDoPathLookup() is used.
Good find, @msftrncs - yes, this originally came up in #4726, at which time paths that happened to be invalid when interpreted _as wildcards_ broke invocation.
This aspect of mistakenly even attempting wildcard resolution _on invocation_ has been fixed in https://github.com/PowerShell/PowerShell/pull/9202 (note that the _redirection_ aspect is still broken), but, as this issue shows, there are still contexts where the executable name is mistakenly treated as a wildcard pattern.
/cc @TravisEz13 For information.
This issue was fixed in PowerShell 7. We will not backport this to previous versions.
Please fill out the issue template completely with all required details if you would like use to re-evaluate (An actual repro, the actual environment you repro'ed it in, the actual expected result)
@TravisEz13:
A _related_ problem was fixed, as detailed in my previous comment, but not this one, which still exists in PowerShell Core 7.0.0-preview.5, on all platforms.
This problem, as detailed by @msftrncs in the OP, is specifically about executables with file names that _look like_ wildcard expressions _not being looked for in $env:PATH_ - an edge case, certainly, but still a bug.
Describe "Execute scripts by file name only via `$env:PATH." {
BeforeAll {
$originalPath= $env:PATH
$dir = Convert-Path TestDrive:
"'hi1'" | Set-Content -LiteralPath $dir/script.ps1
"'hi2'" | Set-Content -LiteralPath $dir/script[1].ps1
$env:PATH += [IO.Path]::PathSeparator + $dir
}
AfterAll {
$env:PATH = $originalPath
}
It "Finds and executes a script with a vanilla file name." {
script.ps1 | Should -Be 'hi1'
}
It "Finds and executes a script whose file name looks like a wildcard." {
script[1].ps1 | Should -Be 'hi2'
}
}
The 2nd test fails with:
CommandNotFoundException: The term 'script[1].ps1' is not recognized as the name of a cmdlet, function, script file, or operable program.
That is, script.ps1 was found, as expected, but script[1].ps1 was unexpectedly not, due to the name containing wildcard characters.
I have some edits available for a PR. It involves removing the test for wildcard characters in CommandSearcher.CanDoPathLookup(). I can produce a PR in a little bit.
Most helpful comment
I have some edits available for a PR. It involves removing the test for wildcard characters in
CommandSearcher.CanDoPathLookup(). I can produce a PR in a little bit.