Powershell Command Processing (Passing in Variables) Powershell Command Processing (Passing in Variables) powershell powershell

Powershell Command Processing (Passing in Variables)


The call operator '&' is unnecessary in this case. It is used to invoke a command in a new scope. This is typically used to invoke a command specified by a string or scriptblock. It also has the side benefit that any variables created in say a PowerShell script are discarded after the command finishes and the scope goes away.

However since the cmd is an EXE it executes in a completely different process. FWIW, you get similar output directly from cmd.exe:

> cmd "/c echo foo"foo"

So the extra quote on the end is a cmd.exe issue. Typically you need to keep the command separate from the parameters when PowerShell is doing the parsing to invoke the command e.g.

45> & { $foo = "foo" }46> $foo  # Note that $foo wasn't found - it went away with the scope47> . { $foo = "foo" } # dotting executes in the current scope48> $foo foo

The notable exception here is that Invoke-Expression behaves like an "evaluate this string" function. Use with care, especially if the user provides the string. Your day could suck if they provided "ri C:\ -r".

In this case, as others have suggested I would pull the /c out of the string $param string and specify it e.g.:

cmd /c $param

Or use Invoke-Expression but use with care. BTW when you are trying to debug issues with sending arguments to EXE from PowerShell, check out the echoargs utility in PowerShell Community Extensions (http://pscx.codeplex.com). It is very handy:

49> $param = "/c echo foo"50> echoargs $paramArg 0 is </c echo foo>

This shows that cmd.exe receives "/c echo foo" as a single argument. "/c" should be a separate argument from "echo foo" (the command to execute).


I have had problems with the & call operator in the past when trying to invoke executable type commands like you are trying. Not sure I understand why. Invoke-Expression however, always seems to work in this context:

PS C:\> $cmd = "cmd /c echo foo"PS C:\> Invoke-expression $cmdfoo


One other way I found to do this was to create an array of arguments for the command line and use that with the apersand & call operator. Something like this:

$exe = "cmd";[Array]$params = "/c", "echo", "foo";& $exe $params;

It's worked well for me.

I originally found this technique here: http://techstumbler.blogspot.com/2009/12/windows-commands-with-arguments-in.html