121

I am having a bunch of issues with getting a PowerShell command to run. All it is doing is running a command that would be run in a CMD prompt window.

Here is the command:

"C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe" PCNAME

I have tried the following with no success (I have tried many iterations of this to try and get one that works. Syntax is probably all screwed up):

$TEXT = $textbox.Text #$textbox is where the user enters the PC name.
$CMDCOMMAND = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe"
Start-Process '"$CMDCOMMAND" $TEXT'
#iex -Command ('"C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe"' $TEXT)

The command will just open SCCM remote connection window to the computer the user specifies in the text box.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user3585839
  • 1,459
  • 3
  • 12
  • 18
  • I'm not sure which version of SCCM you are using, but 07 requires a "-1", but 2012 doesn't when launching CmRcViewer. Just a FYI. – Kevin_ Jul 24 '14 at 20:25

5 Answers5

140

Try this:

& "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe" PCNAME

To PowerShell a string "..." is just a string and PowerShell evaluates it by echoing it to the screen. To get PowerShell to execute the command whose name is in a string, you use the call operator &.

Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • Awesome, this worked. Should that work for most cmd commands? – user3585839 Jul 24 '14 at 18:22
  • 7
    Yes but it is not necessary for exes that don't have a space in their name or path. For instance, you can execute `ipconfig.exe` without having to use `&`. The only time you need to use `&` is to invoke a command name in string form. And you have to use "string form" when there is a space in the path or filename. – Keith Hill Jul 24 '14 at 21:17
  • 19
    I would add that it won't work to construct a command-line string and try to execute with `&`, because PowerShell will think the entire string is the executable's name. Instead quote only the executable's name and put the executable's parameters afterwards. – Bill_Stewart Jul 24 '14 at 21:32
  • What is the diff between `&` and `cmd`? – Timo May 08 '20 at 05:02
  • 3
    `&` is the PowerShell call (aka invocation) operator. It allows you to execute a command when what you have is a string that contains either the command's name or the path to the exe. You can also specify a scriptblock e.g. `&{$foo=42}` or a CommandIno object e.g. `$cmd = Get-Command Get-Date; &$cmd`. `cmd` is a different shell. Note that `&` executes in a child scope so you will note that after the scriptblock that sets `$foo` above finishes, `$foo` is not set anymore. – Keith Hill May 10 '20 at 20:12
  • Adding just this simple character resolved some hours of agonizing over a non-working script. Thanks for the simple and clear explanation. For context, I am updating a Windows 10 autounattend.xml script, which installs Windows silently from a bootable USB, then launches a provisioning batch script: `C:\Windows\SysWOW64\cmd /c PowerShell -NoLogo -ExecutionPolicy RemoteSigned -Command "& \"$((Get-WmiObject Win32_Volume -Filter \"Label='WindowsUSB'\").DriveLetter)\provisioning\run_provisioning.cmd\""` Previously the script would simply echo the command, not execute. – snomsnomsnom Jul 08 '20 at 11:26
88

To run or convert batch files externally from PowerShell (particularly if you wish to sign all your scheduled task scripts with a certificate) I simply create a PowerShell script, e.g. deletefolders.ps1.

Input the following into the script:

cmd.exe /c "rd /s /q C:\#TEMP\test1"

cmd.exe /c "rd /s /q C:\#TEMP\test2"

cmd.exe /c "rd /s /q C:\#TEMP\test3"

*Each command needs to be put on a new line calling cmd.exe again.

This script can now be signed and run from PowerShell outputting the commands to command prompt / cmd directly.

It is a much safer way than running batch files!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Armand G.
  • 1,817
  • 14
  • 8
  • 1
    This worked great for me. I was trying to run: `sc query serviceName` from PowerShell thinking it would execute, but no output. I tried several iterations of the & technique, no dice. But running it the way you recommended worked. Next I hit up cmd.exe /? to see what other wonders awaited me. I only like running cmd when needed. – Paul Masek Jul 03 '20 at 21:40
  • 1
    Thank you! I was trying to run fc.exe, but FC is its very own powershell command, so cmd.exe /c "fc file1.bin file1.bin" worked great! – George D Girton Aug 18 '22 at 13:19
  • For `.exe` file, you can also run them from PowerShell without `cmd` and they *will* execute, you just have to remember that PowerShell can't resolve `sc`, but it can resolve `sc.exe`, so `sc.exe query serviceName` runs just fine. Same for `fc.exe`, just do `fc.ee file1.bin file2.bin` and these commands will run fine in a PowerShell console. – YorSubs Sep 01 '22 at 20:23
17

One solution would be to pipe your command from PowerShell to CMD. Running the following command will pipe the notepad.exe command over to CMD, which will then open the Notepad application.

PS C:\> "notepad.exe" | cmd

Once the command has run in CMD, you will be returned to a PowerShell prompt, and can continue running your PowerShell script.


Edits

CMD's Startup Message is Shown

As mklement0 points out, this method shows CMD's startup message. If you were to copy the output using the method above into another terminal, the startup message will be copied along with it.

InteXX
  • 6,135
  • 6
  • 43
  • 80
reelyard
  • 931
  • 1
  • 8
  • 29
  • 3
    It can work even when `&` does not. E.g. `& "mklink"` did not work for me while `"mklink" | cmd` worked – moudrick Mar 24 '20 at 11:10
3

For those who may need this info:

I figured out that you can pretty much run a command that's in your PATH from a PS script, and it should work.

Sometimes you may have to pre-launch this command with cmd.exe /c

Examples

Calling git from a PS script

I had to repackage a git client wrapped in Chocolatey (for those who may not know, it's a package manager for Windows) which massively uses PS scripts.

I found out that, once git is in the PATH, commands like

$ca_bundle = git config --get http.sslCAInfo

will store the location of git crt file in $ca_bundle variable.

Looking for an App

Another example that is a combination of the present SO post and this SO post is the use of where command

$java_exe = cmd.exe /c where java

will store the location of java.exe file in $java_exe variable.

Wessel van Lit
  • 83
  • 1
  • 11
avi.elkharrat
  • 6,100
  • 6
  • 41
  • 47
  • 1
    You only need `cmd /c` for invoking its _internal_ commands, such as `mklink`. By contrast, `where.exe` is an external program, so you can invoke it directly. However, because of a name conflict with PowerShell's built-in `where` alias (for `Where-Object`), you must use `where.exe`; e.g, `where.exe java`. – mklement0 Nov 14 '18 at 04:26
  • Or just use PowerShell's `Get-Command` instead of calling `cmd`? Same as before: `$java_exe = $(Get-Command java.exe).Source` – dtasev Dec 03 '19 at 16:00
-2

You must use the Invoke-Command cmdlet to launch this external program. Normally it works without an effort.

If you need more than one command you should use the Invoke-Expression cmdlet with the -scriptblock option.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131