Оператор вызова «&» в этом случае не нужен. Он используется для вызова команды в новой области видимости. Обычно это используется для вызова команды, указанной строкой или блоком сценария. Еще одно преимущество заключается в том, что любые переменные, созданные в сценарии PowerShell, отбрасываются после завершения команды и исчезновения области действия.
Однако, поскольку cmd является EXE-файлом, он выполняется в совершенно другом процессе. FWIW, вы получаете аналогичный вывод непосредственно из cmd.exe:
> cmd "/c echo foo"
foo"
Таким образом, дополнительная цитата в конце - это проблема cmd.exe. Обычно вам нужно держать команду отдельно от параметров, когда PowerShell выполняет синтаксический анализ, чтобы вызвать команду, например,
45> & { $foo = "foo" }
46> $foo # Note that $foo wasn't found - it went away with the scope
47> . { $foo = "foo" } # dotting executes in the current scope
48> $foo
foo
Примечательным исключением здесь является то, что Invoke-Expression ведет себя как функция «оценивать эту строку». Используйте с осторожностью , особенно , если пользователь предоставляет строку. Ваш день мог бы отстой, если бы они предоставили "ri C: \ -r".
В этом случае, как предлагали другие, я бы вытащил / c из строки $ param string и указал ее, например ::
cmd /c $param
Или используйте Invoke-Expression, но используйте с осторожностью. Кстати, когда вы пытаетесь отладить проблемы с отправкой аргументов в EXE из PowerShell, проверьте утилиту echoargs в расширениях сообщества PowerShell (http://pscx.codeplex.com). Это очень удобно:
49> $param = "/c echo foo"
50> echoargs $param
Arg 0 is </c echo foo>
Это показывает, что cmd.exe получает "/ c echo foo" в качестве одиночного аргумента. «/ c» должен быть отдельным аргументом от «echo foo» (команда для выполнения).