I am running the following command as part of a test code trying to determine if a script is running in an interactive session (i.e. with a CLI) or if from a console-less remote session (SSH,SCP,FTP).
So when using [Environment]::GetCommandLineArgs()
, in a Powershell Core (pwsh.exe
) CLI session, I get: C:\Program Files\PowerShell\6\pwsh.dll
. This is surprising as I would have expected to get pwsh.exe and not a DLL.
Why do I get the DLL and not the EXE?
What is going on?
This is a known problem that is still not fixed as of .NET 5.0, which PowerShell Core 7.1 is built on (both are in preview as of this writing, but I don't expect a fix to come in time for these releases).
See GitHub issue #11305.
However, there is a workaround that is actually generally preferable:
The reason that
[System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
is preferable to[Environment]::GetCommandLineArgs()[0]
is twofold:The former always reports a full path.
At least up to .NET Core 3.1, the latter can report a temporary location, namely for single-file .NET Core executables that extract themselves to such locations behind the scenes.
Note that .NET 5.0+ will have a dedicated
[Environment]::ProcessPath
property that will also perform better - see GitHub PR #42768.If you want to get a corrected version of
[Environment]::GetCommandLineArgs()
- that is, with the real executable stored at index0
and the true arguments in the remaining elements:To demonstrate with an invocation of the PowerShell CLI from
cmd.exe
: