本文介绍了如何从 Java 程序内部创建 powershell 远程会话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码来连接到远程机器并执行命令.如果我为远程机器的每个 Invoke-Command 调用创建一个新会话,它就可以工作.我不想在每次使用 Invoke-Command 时都创建一个新会话,因为这不会同时扩展数百台机器上的数千个命令,并且会话创建本身就是一个很大的开销.我需要一种方法,以便我可以在 $session powershell 变量中重用相同的会话对象,以便对远程计算机进行多次 Invoke-Command 调用.

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.

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> ");
            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();
}
}

推荐答案

看这里面涉及到很多逻辑可以帮到你.

See there are lot of logics involves in this which can help you.

你的会话调用没问题;但是你不能直接运行这样的 PS 命令.您必须首先调用 powershell.exe,然后您必须向相应的远程命令提供您想要执行的内容.

Your session invoking is fine; But you cannot directly run a PS command like that. You have to invoke the powershell.exe first then you have to give the respective remote commands what you want to execute.

最后,您已执行将要准备的命令.让我与您分享一个示例代码:

Finally you have execute the command you will prepare. Let me share you a sample code:

public String executeScript(String psFileName, Systems system) throws NMAException {

        Runtime runtime = Runtime.getRuntime();
        String filePath = ApplicationProperties.getPropertyValue("powershell.scripts.location");
        String command;

        switch (psFileName) {
            case "TerminalServersSystemInfo.ps1":
                command = POWERSHELL + filePath + psFileName + " " + system.getPassword() + " " + system.getUserName()
                        + " " + system.getSystemName();
                break;
            case "SQLServerInfo.ps1":
                command = POWERSHELL + filePath + psFileName + " " + system.getSystemName() + " "
                        + system.getUserName() + " " + system.getPassword();
                break;
            case "MyPS.ps1":

            {
                command = POWERSHELL + filePath + psFileName + " " + system.getSystemName() + " "
                        + system.getUserName()
                        + " " + system.getPassword() + " " + system.getDatabaseName();
                break;
            }

            default:
                throw new NMAException("not available");
        }

这里是你应该如何在 Java 中形成命令对象,然后你应该执行这个:

Here is how you should form the command object in Java and then you should execute this:

powershell -ExecutionPolicy Bypass -NoLogo -NoProfile -Command {Invoke-command ......}

要触发 PS 文件,您可以使用 -Filepath 开关.

For triggering a PS file you can use the -Filepath switch.

接下来这将帮助您执行该操作:

Next this will help you in executing that:

proc = runtime.exec(command);
            proc.getOutputStream().close();
            InputStream is = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader reader = new BufferedReader(isr);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
            proc.getOutputStream().close();
            LOGGER.info("Command: " + command);
            LOGGER.info("Result:" + sb.toString());
            return sb.toString();

希望它能让你有所收获.

Hope it gives you a set off.

这篇关于如何从 Java 程序内部创建 powershell 远程会话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 14:34