在Java中使用Powershell


在某些場景下,需要在Java程序中使用Powershell進行終端交互,這種情況下當然可以直接使用自帶的Runtime來完成:

Runtime.getRuntime().exec("powershell.exe Get-Item");

 但是這種只適合需要單條指令的情況,而存在多條指令時,無法保證前后指令的關聯性。這里介紹一個第三方的類庫:jPowershell

Maven中引入如下依賴:

<dependency>
    <groupId>com.profesorfalken</groupId>
    <artifactId>jPowerShell</artifactId>
    <version>3.1.1</version>
</dependency>

 接下來,在程序中就可以通過如下方式獲取到一個Powershell的實例:

PowerShell session = PowerShell.openSession();

 PowerShell對象提供了如下的基礎方法:

configuration(Map<String,String> arg0)
指定配置對象 void 修改默認配置時使用
openSession()
  PowerShell 啟動一個PowerShell會話
openSession(String arg0)
指定PowerShell終端的路徑 PowerShell 啟動一個PowerShell會話
executeCommand(String arg0)
Powershell指令 PowerShellResponse 執行一條PowerShell指令
executeSingleCommand()
Powershell指令 PowerShellResponse 執行單一PowerShell指令(無會話模式)
executeCommandAndChain(String arg0,PowerShellResponseHandler.. arg1)
PowerShell指令,Response處理器 PowerShell 執行一條PowerShell指令並對其Response進行處理
handleResponse(PowerShellResponseHandler arg0,PowerShellResponse arg1)
Response處理器,Response void 使用指定Response處理器處理響應
isLastCommandInError()
  boolean 最后一條指令是否出錯
executeScript(String arg0)
腳本路徑 PowerShellResponse 執行指定的腳本
executeScript(String arg0, String arg1) 腳本路徑,執行參數 PowerShellResponse 傳入參數執行指定腳本
executeScript(BufferedReader arg0) 腳本緩沖對象 PowerShellResponse 從緩沖對象中執行腳本
executeScript(BufferedReader arg0, String arg1) 腳本緩沖對象,執行參數 PowerShellResponse 傳入參數執行緩沖對象中的腳本
close()   void 關閉會話
closeAndWait(Future<String> arg0) 異步對象列表 boolean 等待異步對象列表中全部Task完成后關閉會話
checkState()   void

檢查當前會話狀態

獲取到的session對象是一個新的Powershell會話實例,可以通過下述方式來執行指令:

String readContext = "Get-Content D:\\1.sql";
session.executeCommand("$user = \""+username+"\"");
session.executeCommand("$password = ConvertTo-SecureString \"" +password + "\" -AsPlainText -Force");
session.executeCommand("$credential = New-Object System.Management.Automation.PSCredential($user,$password)");
response = session.executeCommand("Invoke-Command -ComputerName " + server + " -Credential $credential -ScriptBlock {" + readContext + "}");
System.out.println(response.getCommandOutput().length());

 

上述代碼中,首先定義了兩個shell變量,$user和$password,而后通過調用System.Management.Automation.PSCredential構造了一個$credential對象,再將其作為-Credential的值傳入下一條指令中,完成遠程Invoke-Command進行文件內容長度的讀取。

每一條session.executeCommand()都會返回一個PowerShellResponse對象,可以通過調用這個對象的getCommandOutput()方法來獲取命令輸出。注意看日志最后的數字:

當然,在某些情況下,調用的指令執行時間會很長,在默認情況下,Powershell實例只會等待10秒鍾,如果10秒鍾之后還沒有返回值,就直接跳到下一條繼續執行了。這種情況下,可以通過配置Powershell的實例來修改等待時間。來看源碼:

public class PowerShell implements AutoCloseable {
    private static final Logger logger = Logger.getLogger(PowerShell.class.getName());
    private Process p;
    private long pid = -1L;
    private PrintWriter commandWriter;
    private boolean closed = false;
    private ExecutorService threadpool;
    private static final String DEFAULT_WIN_EXECUTABLE = "powershell.exe";
    private static final String DEFAULT_LINUX_EXECUTABLE = "powershell";
    private int waitPause = 5;
    private long maxWait = 10000L;
    private File tempFolder = null;
    private boolean scriptMode = false;
    public static final String END_SCRIPT_STRING = "--END-JPOWERSHELL-SCRIPT--";
 
    private PowerShell() {
    }
 
    public PowerShell configuration(Map<String, String> config) {
        try {
            this.waitPause = Integer.valueOf(config != null && config.get("waitPause") != null ? (String)config.get("waitPause") : PowerShellConfig.getConfig().getProperty("waitPause"));
            this.maxWait = Long.valueOf(config != null && config.get("maxWait") != null ? (String)config.get("maxWait") : PowerShellConfig.getConfig().getProperty("maxWait"));
            this.tempFolder = config != null && config.get("tempFolder") != null ? this.getTempFolder((String)config.get("tempFolder")) : this.getTempFolder(PowerShellConfig.getConfig().getProperty("tempFolder"));
        } catch (NumberFormatException var3) {
            logger.log(Level.SEVERE, "Could not read configuration. Using default values.", var3);
        }
 
        return this;
    }
}

 Powershell提供了一個configuration()方法,這個方法接受一個Map類型的配置參數,並將內容解析后代替默認參數。我們主要關注的是maxWait的值。通過成員定義可以看出,默認的maxWait的值就是10000毫秒,也就是10秒。因此,可以通過如下代碼來使其支持更長時間指令的調用:

PowerShell session = PowerShell.openSession();
Map<String,String> configMap = new HashMap<>();
configMap.put("maxWait","600000");
session.configuration(configMap);

 這樣就把指令的最長等待時間設置為了600秒。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM