-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Description
On both Windows and Unix platforms, Start-Process -UseNewEnvironment
results in an environment that is missing crucial standard environment variables, making the new environment virtually useless, while not providing a mechanism to define a new environment:
-
On Windows,
-UseNewEnvironment
defines only the variables that are explicitly defined, as displayed in System Properties (sysdm.cpl
), with crucial, usually automatically defined variables such as$env:ProgramFiles
missing, and$env:USERNAME
unexpectedly containingSYSTEM
.- This even prevents another
powershell
instance from being started this way - see Start-Process fails to launch new powershell.exe instance with -UseNewEnvironment switch #3545 (comment) and below.
- This even prevents another
-
On Unix, an empty environment is essentially passed (with no environment variables defined at all, except
$env:PSModulePath
).-
This even prevents invoking any executable by filename only, given that
$env:PATH
is undefined - see below. -
While this behavior is similar to POSIX
env -i
on Unix platforms, theenv
utility notably includes a mechanism to provide a new environment vianame=value
pairs, whichStart-Process
lacks.
-
Possible solutions:
-
Repurpose
-UseNewEnvironment
to not start with a blank slate / crucial variables missing, but to provide the same environment that a shell would see when directly launched by the system (in other words: any environment-variable modifications made by the calling shell would be ignored). -
Additionally, provide a way to pass a custom environment, applied on top of the current or pristine (
-UseNewEnvironment
) environment:-
E.g., a new
-Environment <hashtable>
/-Environment <Collections.DictionaryEntry[]>
parameter could be used. -
If someone truly wanted an empty environment, they could start with
$emptyEnv = (Get-ChildItem env:); $emptyEnv | % { $_.Value = $null }
and pass-Environment $emptyEnv
.
-
The -Environment
feature would allow for an - incomplete - approximation of the convenient ad-hoc, command-scoped environment-variable definition feature that POSIX-like shells such as bash
offer, where you can prepend one or more name=value
pairs to a command:
# Bash (any POSIX-compatible shell)
# Defines $env:FOO as 'bar', but *only for the some-utility child process*.
FOO=bar some-utility 666
Update: #3316 suggests emulating this syntax in PowerShell, which would be the best solution.
The PS approximation would be:
Start-Process -Wait -Environment @{ FOO = 'bar' } some-utility -Args 666
That said, a crucial limitation is that use of Start-Process
makes the external utility operate outside PowerShell's streams, so the only way to provide input / collect output is via the -Redirect*
parameters, which requires auxiliary files.
Current behavior
Start-Process -UseNewEnvironment -Wait -NoNewWindow pwsh -args '-Command', 'gci env:; whoami'
- On Windows: PowerShell refuses to start - see Start-Process fails to launch new powershell.exe instance with -UseNewEnvironment switch #3545; note that adding
-LoadUserProfile
makes no difference.
Internal Windows PowerShell error. Loading managed Windows PowerShell failed with error 8009001d.
- On Unix: PowerShell starts, lists
$env:PSModulePath
as the only environment variable - with a seemingly temporary user account's module directory prepended - and thewhoami
invocation fails, because it cannot be located in the absence of a suitable$env:PATH
.
Name Value
---- -----
PSModulePath /tmp/ba38e79f-40c2-440e-ae08-7cf32e0708e1/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/opt/microsoft/...
whoami : The term 'whoami' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
At line:1 char:21
+ Get-ChildItem env:; whoami
+ ~~~~~~
+ CategoryInfo : ObjectNotFound: (whoami:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Environment data
PowerShell Core v6.0.0-beta.5 on macOS 10.12.6
PowerShell Core v6.0.0-beta.5 on Ubuntu 16.04.3 LTS
PowerShell Core v6.0.0-beta.5 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Windows PowerShell v5.1.15063.483 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)