profesorfalken / jPowerShell

Simple Java API to interact with PowerShell console
Apache License 2.0
218 stars 84 forks source link

Premature Termination #10

Closed michael-hay closed 8 years ago

michael-hay commented 8 years ago

Similar to the other open issue

https://github.com/profesorfalken/jPowerShell/issues/9

I'm seeing that if I open a PSSession and feed it commands it will terminate after it gets the first ouput line instead of waiting for an exit code. So What I'm trying to do is this:

private static String executePowerShellCmd(PowerShell powerShell, String cmd, String timeout) {
    printCmd(cmd);
    Map<String, String> myConfig = new HashMap<>();
    myConfig.put("maxWait", timeout);
    PowerShellResponse response = powerShell.configuration(myConfig).executeCommand(cmd);
    return response.getCommandOutput();
}

public static void executeRemoteSession(String cmd, String automationHome, String serverName, String timeout) throws Exception {
    PowerShell powerShell = null;
    try {
        powerShell = PowerShell.openSession();
        System.out.println(executePowerShellCmd(powerShell, "$s = New-PSSession -ComputerName " + serverName, "10"));
        System.out.println(executePowerShellCmd(powerShell, "Invoke-Command -Session $s {" + cmd + "}", timeout));
        System.out.println(executePowerShellCmd(powerShell, "Get-PsSession -ComputerName  " + serverName + " | Remove-PsSession", "10"));
    } catch(PowerShellNotAvailableException ex) {
        throw new RuntimeException("Failed to run PowerShell", ex);
    } finally {
        if (powerShell != null)
             powerShell.close();
    }
}

So if I try a remote command on another server that may say execute a ps1 script it will not do a p.waitfor() and get me a return code. Your function executeCommand() will terminate on the first output it receives.

I tried the execute script function but that has another issue. It assumes that you are running the script locally on the same server. I'm not. I'm opening a remote PSSession and running a script on a remote server.

I think if you just put in a p.waitfor() in your code that would hold the executeCommand() function till the remote script completes. However I think that will interfere with your ability to timeout. Maybe a new function that does this with no timeout would be in order. Not sure.

I'm using jPowerShell-1.6.2, tried very long timeout values for the Invoke-Command still terminates on first output it receives.

michael-hay commented 8 years ago

Ohhh I see. Since we are doing this

ProcessBuilder pb = new ProcessBuilder("powershell.exe", "-NoExit", "-Command", "-"); p = pb.start();

then feeding it commands, p never actually terminates. So any call to p.waitFor() will never exit. Interesting. Is there a way we could do something like p.waitFor() on each command we are passing to Process p?

profesorfalken commented 8 years ago

Hello, Yes, it is exactly that. With Powershell the problem is that what the process we launch is the powershell interpreter. Then, we send the commands to this process and wait for a result.

There is no return code of the process since the only process we can handle is this of powershell.exe itself.

See the comments in the issue #11

profesorfalken commented 8 years ago

Closed as duplicated