title: how to create a powershell remote session from inside a Java program?
body: <p>I have the following code to connect to a remote machine and execute commands.It is working if I create a new session for each Invoke-Command call to the remote machine. I don't want to create a new session each time I use Invoke-Command as that will not scale for thousands of commands on hundreds of machines concurrently and session creation itself is a big overhead. I need a way so that I can reuse the same session object in the $session powershell variable for multiple Invoke-Command calls to the remote machines.</p>
  
  <pre><code>import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.util.Scanner;
  
  public class PowerShellSession {
  
  private static String subModule = "PowerShellSession";
  String targetIpAddress;
  String username;
  String password;
  
  public static Object connectPShellLock = new Object();
  
  public PowerShellSession() {}
  
  
  public void exec(String cmd, String credentials)  { 
  
      String ex = "Invoke-Command -Session $session -ScriptBlock {" + cmd + "} -Computer " + targetIpAddress;
  
      String[] args = new String[] { "powershell", ex};
      try {
          execRemote(args);
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
  
  public void close() {
      String command = "Exit-PSSession";
      String[] args = new String[] { "powershell", command};
      try {
          execRemote(args);
      } catch (IOException e) {
          e.printStackTrace();
      }
  
  }
  
  private String getCredentials(String domain, String userName,
          String password) throws IOException {
      String creds = "$PlainPassword ='" + password
              + "'; $SecurePassword = $PlainPassword | ConvertTo-SecureString -AsPlainText -Force;"
              + "$mycred = new-object -typename System.Management.Automation.PSCredential('" + userName + "', $SecurePassword);";
      creds += "$session = New-PSSession -ComputerName " + domain + " -Credential $mycred;";
  
      String[] args = new String[] { "powershell", creds};
      execRemote(args);
      return creds;
  }
  
  private void execRemote(String[] arguments) throws IOException {
      ProcessBuilder builder = new ProcessBuilder(arguments);
      builder.redirectErrorStream(true);
      Process process = builder.start();
      doProcessIO(process);
  }
  
  // Do the IO for a passed process
  private void doProcessIO(Process p) throws IOException {
      p.getOutputStream().close();
      String line;
      System.out.println("Output:");
      BufferedReader stdout = new BufferedReader(new InputStreamReader(
              p.getInputStream()));
      while ((line = stdout.readLine()) != null) {
          System.out.println(line);
      }
      stdout.close();
      System.out.println("Error:");
      BufferedReader stderr = new BufferedReader(new InputStreamReader(
              p.getErrorStream()));
      while ((line = stderr.readLine()) != null) {
          System.out.println(line);
      }
      stderr.close();
  //      System.out.println("Done");
  }
  
  public static void main(String[] args) throws IOException {
      PowerShellSession psSession = new PowerShellSession();
      String credentials = psSession.getCredentials("9.120.241.195", "username", "password");
      psSession.targetIpAddress = "9.120.241.195";
      if(!credentials.equals("")) {
          Scanner input = new Scanner(System.in);
          while(true) {
              System.out.print("PS C:\\Windows\\system32&gt; ");
              String cmd = input.nextLine();
              if(cmd.equals("q") || cmd.equals("e") || cmd.equals("quit") || cmd.equals("exit")) break;
              psSession.username = "username";
              psSession.password = "password";
              psSession.exec(cmd, "");
          }
          System.out.println("Finished PowerShell remote session.");
          input.close();
      }
      psSession.close();
  }
  }
  </code></pre>