PowerShell / PowerShell/PowerShell

Add support for passing arguments to `Invoke-Expression`

Open
#23,836 20 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Issue-Enhancement Needs-Triage
Dominant language
C#
Stars
55.5k
Forks
8.5k
Avg merge
1d 2h
Merged PRs (30d)
88

Description

Summary of the new feature / enhancement

This is a follow-up on one specific aspect of #8816.

The irm ... | iex pattern is well-known and widely used for installing software, similarly to curl ... | sh on POSIX-like systems. We may not be happy about it, but it is widely used, and projects will use continue to use it in the future unless Invoke-Expression is removed alltogether.

#8816 floated some alternative options, converging on extending Invoke-Command. However, compatibility across all commonly used versions of PowerShell is vital for an installer script; a script that only works on some versions of PowerShell is not very useful as a one-liner, since now you have to give multiple one-liners and make the user choose based on the version of PowerShell they're using. This gives me a strong reason to believe that software vendors (including me) will NOT switch to any new backwards-imcompatible option to run downloaded scripts in one command.

One of the limitations of irm ... | iex mentioned in #8816 was that there's no intuitive way to pass optional arguments to the installer script. Unlike some of the issues, I believe that this issue may be resolved in a backwards-compatible way by allowing Invoke-Expression to receive additional arguments and passing them to the invoked script.

Users on older versions of PowerShell will still be able to use the iex "& {$(irm ...)} arg" hack shown in the original issue, while users on new versions of PowerShell can pass arguments the way they would intuitively expect, the same way as with curl ... | sh.

Proposed technical implementation details (optional)

Add a new -ArgumentList parameter to Invoke-Expression, with Parameter(ValueFromRemainingArguments = true). As a result, users should be able to do the following:

irm ... | iex arg -Flag1 -Flag2

If the script provides a param() block, the arguments should be bound as if the script was invoked as a scriptblock with &.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Invoke-Expression entry point and the proposal in #8816, then trace how its parameters are bound. Check the implications of adding -ArgumentList with ValueFromRemainingArguments and passing values to a script's param() block. Done means supporting the shown irm ... | iex arg -Flag1 -Flag2 form while preserving existing behavior and the older compatibility workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, powershell
Domain
cli
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.