Invoke-Expression considered harmful

The PowerShell team frequently gets questions that start out “how do I get the quoting right for…” and the answer turns out to usually be – there is a simpler way – don’t use Invoke-Expression.

The problem arises when trying to run some command external to PowerShell.  Some common reasons people try Invoke-Expression:

  • running some command with a space in the path
  • some command takes an argument with characters that have special meaning in PowerShell, e.g. curly braces (‘{‘ and ‘}’)
  • some command argument needs to use a PowerShell variable, perhaps as part of a quoted argument

If you’re just running some command external to PowerShell (exe, cmd, etc.) and you’re using Invoke-Expression, you are just making things more difficult than you need to.

So what’s wrong with Invoke-Expression then?

  • It complicates getting quoting right
  • It makes maintaining your script harder
  • It’s slower than the alternatives
  • And maybe worst of all – it opens up a script to code injection attacks

If Invoke-Expression isn’t the right way – then what is?

If you’re running some command and the command path has spaces in it, then you need the command invocation operator ‘&’ (see help about_operators, look for “call operator”).

If your command runs, but your arguments are wrong, then there is a good chance you are getting the quotes wrong.  Invoke-Expression doesn’t help at all in this case, it just makes the problem more complicated. 

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.

Jason Shirk
Windows PowerShell Team