Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

powershell

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?

like image 397
Bender the Greatest Avatar asked Jul 09 '18 19:07

Bender the Greatest


People also ask

What does invoke-expression do?

Description. The Invoke-Expression cmdlet evaluates or runs a specified string as a command and returns the results of the expression or command. Without Invoke-Expression , a string submitted at the command line is returned (echoed) unchanged. Expressions are evaluated and run in the current scope.

What port does invoke-command use?

The default ports are 5985, which is the WinRM port for HTTP, and 5986, which is the WinRM port for HTTPS. Do not use the Port parameter unless you must. The port that is set in the command applies to all computers or sessions on which the command runs.

How do I run CMD as administrator?

The only way to get a remote PowerShell session to execute elevated (with admin privileges) is to connect with a user account (either implicitly or via -Credential ) that has admin privileges on the target machine. With such an account, the session automatically and invariably runs elevated.


1 Answers

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.

Note: As of Windows PowerShell v5.1 / PowerShell Core v6.1.0, the official Invoke-Expression help topic doesn't provide such guidance; this GitHub issue suggests rectifying that.


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

  • Creating PSv5+ custom classes dynamically:

    • so that the class can be used in a remote session.

    • so that the set of properties can be created based on conditions at runtime.

  • Using Invoke-Expression in combination with Write-Output:

    • to parse a string with embedded quoting, with extra precautions.

    • to parse command lines stored in a file, if trusted.

  • Using Invoke-Expression for nested property access:

    • via a property path stored in a string.
like image 111
mklement0 Avatar answered Nov 16 '22 02:11

mklement0