java - 如何从 Java 程序内部创建 powershell 远程 session ?

标签 java powershell remoting winrm

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

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

最佳答案

看看这里面涉及很多逻辑,可以帮助你。

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

最后你已经执行了你准备的命令。让我分享一个示例代码:

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 中形成命令对象,然后执行它:

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

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

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

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

希望它能给你带来启发。

关于java - 如何从 Java 程序内部创建 powershell 远程 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43061714/

相关文章:

java - Heroku:如何指定JVM buildpack非java项目的路径?

java - Maven Jsoup 缺少 Artifact 异常

powershell - 如何从 Powershell 获取退出代码并返回到 CMD?

c# - PowerShell 远程处理 Lync、Active Directory 搜索域 Controller 时出现错误 "-2147016672"

visual-studio - 如何在 Visual Studio 2008 中调试透明代理实例?

.net - 将 .Net 远程处理与 ipv6 结合使用

java - 如何在 Java 中显式调用静态初始化器?

java - java中精确获取小数点后的值

powershell - 如何在 Windows 10 PowerShell 上禁用语法高亮显示?

Powershell Get-Process 字符串作为名称