Skip to content

Start-Process -UseNewEnvironment provides an environment that is missing crucial standard environment variables while not supporting passing a new environment #4671

@mklement0

Description

@mklement0

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 containing SYSTEM.

  • 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, the env utility notably includes a mechanism to provide a new environment via name=value pairs, which Start-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'
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 the whoami 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugKeepOpenThe bot will ignore these and not auto-closeWG-Cmdlets-Managementcmdlets in the Microsoft.PowerShell.Management moduleWG-ReviewedA Working Group has reviewed this and made a recommendation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions