In what scenario was Invoke-Expression designed to be used?
Asked Answered
R

1

9

9/10 times if you are trying to use the Invoke-Expression cmdlet, there is a better way. Building the arguments to a command dynamically? Use an array of arguments. Building the arguments to a cmdlet? Use splatting with an array or hashtable. Your command has a space in the path to it? Use the call operator (&).

This might seem open ended, but Invoke-Expression is an easily accessible cmdlet where the answer is almost always to never use it. But the cmdlet exists for a reason, is not deprecated, and most criticisms of its use state something similar to, "it's almost never the right answer", but never states when it is acceptable to use it. In what case is it acceptable to use Invoke-Expression? Or to word it a bit less openly, how was Invoke-Expression designed to be used?

Runaway answered 9/7, 2018 at 19:6 Comment(0)
E
15

Update: An official deep-dive topic is now available: Avoid using Invoke-Expression


To quote from a PowerShell team blog post titled Invoke-Expression considered harmful (emphasis added):

The bottom line: Invoke-Expression is a powerful and useful command for some scenarios such as creating new scripts at runtime, but in general, if you find yourself using Invoke-Expression, you should ask yourself, or maybe a respected colleague if there is a better way.

EBGreen notes:

Or to phrase it another way, It [Invoke-Expression] is ok to use as long as a user is never involved in any part of generating the string that will be invoked. But even then, not using it will enforce better habits than using it would.

In short:

  • As a matter of habit, always consider a different (usually more robust and secure) solution first.

  • If you do find that Invoke-Expression is your only choice, carefully consider the security implications: if a string from an (untrusted) outside source (e.g., user input) is passed directly to Invoke-Expression, arbitrary commands may be executed.

    • Therefore: Only use Invoke-Expression if you fully control or implicitly trust the input.

Rare examples of justified (safe) use of Invoke-Expression:

Estelaestele answered 9/7, 2018 at 19:18 Comment(3)
Thanks, this answers my question, and I can still think of other techniques other than using Invoke-Expression for running scripts entirely constructed within Powershell for most circumstances. So my takeaway is that there is always a better solution than Invoke-Expression.Runaway
@BendertheGreatest: Glad to hear it. I wouldn't say always, but in most cases; please see my update.Estelaestele
Both cases I did not take into consideration, though I can't say I regularly (or ever) create Powershell classes on the fly. Can see how it would be useful over a collection of NoteProperties though, if the use case justifies the extra work to devise a class dynamically.Runaway

© 2022 - 2024 — McMap. All rights reserved.