Search code examples
powershellexecblockingwsh

Calling Powershell with WshShell.Exec() method hangs the script


I am trying to call Powershell with the Exec method of the WshShell object. I am writing the script in JScript, but I have reproduced the problem in VBScript as well. Both of the following short test scripts will cause WSH to hang indefinitely:

test.js

var shell = new ActiveXObject("WScript.Shell");
WScript.Echo(shell.exec("powershell -Command $Host.Version; Exit").StdOut.ReadAll());

test.vbs

dim shell

set shell = CreateObject("WScript.Shell")
WScript.Echo shell.exec("powershell -Command $Host.Version; Exit").StdOut.ReadAll

Am I doing something wrong, or am I running into or a limitation/incompatibility? The Run method works very well, but I need to capture output, which it's not capable of doing.

Edit: I forgot to mention that my platform is Windows 7 Pro, 64-bit with PowerShell 3. I've tested on Windows XP with PowerShell 1 as well.

Edit 2: I've updated the test scripts that I'm running to fit with x0n's answer. Unfortunately, I'm still having trouble. Here are my current tests:

test.js:

var shell = new ActiveXObject("WScript.Shell");
WScript.Echo(shell.exec('powershell -noninteractive -noprofile -Command "& { echo Hello_World ; Exit }"').StdOut.ReadAll());

test.vbs:

dim shell

set shell = CreateObject("WScript.Shell")
WScript.Echo shell.exec("powershell -noninteractive -noprofile -Command ""& { echo Hello_World ; Exit }""").StdOut.ReadAll

Solution

  • You have to close StdIn:

    var shell = new ActiveXObject("WScript.Shell");
    var exec = shell.Exec('powershell -noninteractive -noprofile -Command "& { echo Hello_World ; Exit }"');
    exec.StdIn.Close();
    WScript.Echo(exec.StdOut.ReadAll());
    

    Microsoft said:

    StdIn is still open so PowerShell is waiting for input. (This is an
    "implementation consideration" that we're hoping to fix in V2. The
    PowerShell executable gathers all input before processing.) So
    objexec.StdIn.Close() needs to be added.