diff --git a/pom.xml b/pom.xml
index ea23320e..035ed824 100644
--- a/pom.xml
+++ b/pom.xml
@@ -138,7 +138,7 @@
org.jvnet.jax-ws-commons
jaxws-maven-plugin
- 2.3
+ 2.2
org.codehaus.mojo
diff --git a/winrm4j/src/main/java/io/cloudsoft/winrm4j/winrm/WinRmTool.java b/winrm4j/src/main/java/io/cloudsoft/winrm4j/winrm/WinRmTool.java
index 5158935a..8af77910 100644
--- a/winrm4j/src/main/java/io/cloudsoft/winrm4j/winrm/WinRmTool.java
+++ b/winrm4j/src/main/java/io/cloudsoft/winrm4j/winrm/WinRmTool.java
@@ -25,11 +25,30 @@ private WinRmTool(String address, String username, String password) {
this.password = password;
}
+ /**
+ * Execute a list of Windows Native commands as one command.
+ * The method translates the list of commands to a single String command with a " & " delimiter and a terminating one.
+ */
public WinRmToolResponse executeScript(List commands) {
- return executeScript(joinScript(commands));
+ return executeCommand(joinCommands(commands));
}
+ /**
+ * @deprecated please use {@link #executeCommand(String)}
+ */
public WinRmToolResponse executeScript(String commands) {
+ return executeCommand(commands);
+ }
+
+ /**
+ * Executes a Native Windows command.
+ * It is creating a new Shell on the destination host each time it is being called.
+ * @param command The command is limited to 8096 bytes.
+ * Maximum length of the command can be even smaller depending on the platform.
+ * https://support.microsoft.com/en-us/kb/830473
+ * @since 0.2
+ */
+ public WinRmToolResponse executeCommand(String command) {
Builder builder = WinRmClient.builder(getEndpointUrl());
if (username != null && password != null) {
builder.credentials(username, password);
@@ -40,7 +59,7 @@ public WinRmToolResponse executeScript(String commands) {
StringWriter err = new StringWriter();
try {
- int code = client.command(commands, out, err);
+ int code = client.command(command, out, err);
return new WinRmToolResponse(out.toString(), err.toString(), code);
} finally {
client.disconnect();
@@ -58,27 +77,31 @@ private String getEndpointUrl() {
}
}
+ /**
+ * Executes a Power Shell command.
+ * It is creating a new Shell on the destination host each time it is being called.
+ * @since 0.2
+ */
+ public WinRmToolResponse executePs(String psCommand) {
+ return executeCommand(compilePs(psCommand));
+ }
+
+ /**
+ * Execute a list of Power Shell commands as one command.
+ * The method translates the list of commands to a single String command with a "\r\n" delimiter and a terminating one.
+ */
public WinRmToolResponse executePs(List commands) {
- return executeScript(compilePs(joinPs(commands)));
+ return executeCommand(compilePs(joinPs(commands)));
}
- private String compilePs(String psScript) {
+ public static String compilePs(String psScript) {
byte[] cmd = psScript.getBytes(Charset.forName("UTF-16LE"));
String arg = javax.xml.bind.DatatypeConverter.printBase64Binary(cmd);
return "powershell -encodedcommand " + arg;
}
- /**
- * Batch Script commands appear verbatim in the XML and JAXB will
- * serialize "\r\n" as "
\n" in XML which is not recognized
- * by the Windows service (doesn't unescape
). Since new lines
- * in XML are represented as a single "\n" anyway it's fine to
- * use it as a separator here.
- *
- * TODO cover the case where \r appears in the command?
- */
- private String joinScript(List commands) {
- return join(commands, "\n");
+ private String joinCommands(List commands) {
+ return join(commands, " & ");
}
/**
diff --git a/winrm4j/src/test/java/io/cloudsoft/winrm4j/winrm/AbstractWinRmToolLiveTest.java b/winrm4j/src/test/java/io/cloudsoft/winrm4j/winrm/AbstractWinRmToolLiveTest.java
index e3bb8583..f9330449 100644
--- a/winrm4j/src/test/java/io/cloudsoft/winrm4j/winrm/AbstractWinRmToolLiveTest.java
+++ b/winrm4j/src/test/java/io/cloudsoft/winrm4j/winrm/AbstractWinRmToolLiveTest.java
@@ -69,9 +69,9 @@ protected void assertExecFails(List cmds) {
protected void assertExecPsFails(String cmd) {
Stopwatch stopwatch = Stopwatch.createStarted();
- assertFailed(cmd, executePs(ImmutableList.of(cmd)), stopwatch);
+ assertFailed(cmd, executePs(cmd), stopwatch);
}
-
+
protected void assertExecPsFails(List cmds) {
Stopwatch stopwatch = Stopwatch.createStarted();
assertFailed(cmds, executePs(cmds), stopwatch);
@@ -82,6 +82,11 @@ protected void assertExecSucceeds(String cmd, String stdout, String stderr) {
assertSucceeded(cmd, executeScript(ImmutableList.of(cmd)), stdout, stderr, stopwatch);
}
+ protected void assertExecCommand(String cmd, String stdout, String stderr, int exitCode) {
+ Stopwatch stopwatch = Stopwatch.createStarted();
+ assertWinRmToolResponse(cmd, executeCommand(cmd), stdout, stderr, stopwatch, exitCode);
+ }
+
protected void assertExecSucceeds(List cmds, String stdout, String stderr) {
Stopwatch stopwatch = Stopwatch.createStarted();
assertSucceeded(cmds, executeScript(cmds), stdout, stderr, stopwatch);
@@ -89,7 +94,7 @@ protected void assertExecSucceeds(List cmds, String stdout, String stder
protected void assertExecPsSucceeds(String cmd, String stdout, String stderr) {
Stopwatch stopwatch = Stopwatch.createStarted();
- assertSucceeded(cmd, executePs(ImmutableList.of(cmd)), stdout, stderr, stopwatch);
+ assertSucceeded(cmd, executePs(cmd), stdout, stderr, stopwatch);
}
protected void assertExecPsSucceeds(List cmds, String stdout, String stderr) {
@@ -111,6 +116,15 @@ protected WinRmToolResponse assertSucceeded(Object cmd, WinRmToolResponse respon
if (stderr != null) assertEquals(response.getStdErr().trim(), stderr, msg);
return response;
}
+
+ protected WinRmToolResponse assertWinRmToolResponse(Object cmd, WinRmToolResponse response, String stdout, String stderr, Stopwatch stopwatch, int exitCode) {
+ String msg = "statusCode="+response.getStatusCode()+"; out="+response.getStdOut()+"; err="+response.getStdErr();
+ LOG.info("Executed in "+makeTimeStringRounded(stopwatch)+" (asserting success): "+msg+"; cmd="+cmd);
+ assertEquals(response.getStatusCode(), exitCode, msg);
+ if (stdout != null) assertEquals(response.getStdOut().trim(), stdout, msg);
+ if (stderr != null) assertEquals(response.getStdErr().trim(), stderr, msg);
+ return response;
+ }
protected WinRmToolResponse executeScript(String script) {
return executeScript(ImmutableList.of(script));
@@ -124,25 +138,37 @@ protected WinRmToolResponse executeScript(final List script) {
}});
}
- protected WinRmToolResponse executePs(String script) {
- return executePs(ImmutableList.of(script));
+ protected WinRmToolResponse executeCommand(final String command) {
+ return callWithRetries(new Callable() {
+ @Override public WinRmToolResponse call() throws Exception {
+ WinRmTool winRmTool = WinRmTool.connect(VM_HOST + ":" + VM_PORT, VM_USER, VM_PASSWORD);
+ return winRmTool.executeCommand(command);
+ }});
}
-
- protected WinRmToolResponse executePs(final List script) {
+
+ protected WinRmToolResponse executePs(final String command) {
return callWithRetries(new Callable() {
@Override public WinRmToolResponse call() throws Exception {
WinRmTool winRmTool = WinRmTool.connect(VM_HOST + ":" + VM_PORT, VM_USER, VM_PASSWORD);
- return winRmTool.executePs(script);
+ return winRmTool.executePs(command);
}});
}
- protected WinRmToolResponse executePs(final WinRmTool winRmTool, final List script) {
+ protected WinRmToolResponse executePs(final List script) {
+ return callWithRetries(new Callable() {
+ @Override public WinRmToolResponse call() throws Exception {
+ WinRmTool winRmTool = WinRmTool.connect(VM_HOST + ":" + VM_PORT, VM_USER, VM_PASSWORD);
+ return winRmTool.executePs(script);
+ }});
+ }
+
+ protected WinRmToolResponse executePs(final WinRmTool winRmTool, final String command) {
return callWithRetries(new Callable() {
@Override public WinRmToolResponse call() throws Exception {
- return winRmTool.executePs(script);
+ return winRmTool.executePs(command);
}});
}
-
+
protected WinRmTool connect() throws Exception {
return callWithRetries(new Callable() {
@Override public WinRmTool call() throws Exception {
@@ -184,9 +210,9 @@ protected void copyTo(InputStream source, String destination) throws Exception {
} else {
chunk = Arrays.copyOf(inputData, bytesRead);
}
- executePs(ImmutableList.of("If ((!(Test-Path " + destination + ")) -or ((Get-Item '" + destination + "').length -eq " +
+ executePs("If ((!(Test-Path " + destination + ")) -or ((Get-Item '" + destination + "').length -eq " +
expectedFileSize + ")) {Add-Content -Encoding Byte -path " + destination +
- " -value ([System.Convert]::FromBase64String(\"" + new String(BaseEncoding.base64().encode(chunk)) + "\"))}"));
+ " -value ([System.Convert]::FromBase64String(\"" + new String(BaseEncoding.base64().encode(chunk)) + "\"))}");
expectedFileSize += bytesRead;
}
}
diff --git a/winrm4j/src/test/java/io/cloudsoft/winrm4j/winrm/WinRmToolExecLiveTest.java b/winrm4j/src/test/java/io/cloudsoft/winrm4j/winrm/WinRmToolExecLiveTest.java
index d5156061..4b796859 100644
--- a/winrm4j/src/test/java/io/cloudsoft/winrm4j/winrm/WinRmToolExecLiveTest.java
+++ b/winrm4j/src/test/java/io/cloudsoft/winrm4j/winrm/WinRmToolExecLiveTest.java
@@ -75,7 +75,39 @@ public void testExecFailingScript() throws Exception {
@Test(groups="Live")
public void testExecScriptExit0() throws Exception {
assertExecSucceeds("exit /B 0", "", "");
- assertExecSucceeds(ImmutableList.of("exit /B 0"), "", "");
+ }
+
+ @Test(groups = "Live")
+ public void testChainCommands() {
+ assertExecCommand("echo Hi & echo World", "Hi \r\nWorld", "", 0);
+ }
+
+ /**
+ * Please bear in mind this behavior when executing commands.
+ */
+ @Test(groups="Live")
+ public void testExecRNSplitExit() throws Exception {
+ assertExecCommand("echo Hi\r\necho World\r\n", "Hi", "", 0);
+ assertExecCommand("echo Hi\r\necho World", "Hi", "", 0);
+ assertExecCommand("echo Hi\necho World\n", "Hi", "", 0);
+ assertExecCommand("echo Hi\necho World", "Hi", "", 0);
+ }
+
+ /**
+ * Please bear in mind this behavior when executing commands.
+ */
+ @Test(groups="Live")
+ public void testExecCommandExit() throws Exception {
+ assertExecCommand("exit /B 0", "", "", 0);
+ assertExecCommand("exit /B 1", "", "", 0);
+ assertExecCommand("exit 1", "", "", 0);
+ assertExecCommand("dslfkdsfjskl", "", null, 1);
+ }
+
+ @Test(groups = "Live")
+ public void testExecPowershellExit() throws Exception {
+ assertExecCommand(WinRmTool.compilePs("exit 123"), "", "", 123);
+ assertExecCommand(WinRmTool.compilePs("Write-Host Hi World\r\nexit 123"), "Hi World", "", 123);
}
/*
@@ -239,7 +271,7 @@ public void testExecPsBatchFileExit3() throws Exception {
String scriptPath = "C:\\myscript-"+makeRandomString(8)+".bat";
copyTo(new ByteArrayInputStream(script.getBytes()), scriptPath);
- WinRmToolResponse response = executePs(ImmutableList.of("& '"+scriptPath+"'"));
+ WinRmToolResponse response = executePs("& '"+scriptPath+"'");
String msg = "statusCode="+response.getStatusCode()+"; out="+response.getStdOut()+"; err="+response.getStdErr();
assertEquals(response.getStatusCode(), 3, msg);
}
@@ -347,7 +379,7 @@ public void testConfirmUseOfErrorActionPreferenceDoesNotCauseErr() throws Except
public void testExecPsExit1() throws Exception {
// Single commands
assertExecPsFails("exit 1");
- assertExecPsFails(ImmutableList.of("exit 1"));
+ assertExecPsFails("exit 1");
// Multi-part
assertExecPsFails(ImmutableList.of(PS_ERR_ACTION_PREF_EQ_STOP, "Write-Host myline", "exit 1"));
@@ -372,11 +404,11 @@ public void testToolReuse() throws Exception {
WinRmTool winRmTool = connect();
Stopwatch stopwatch = Stopwatch.createStarted();
- WinRmToolResponse response = executePs(winRmTool, ImmutableList.of("echo myline"));
+ WinRmToolResponse response = executePs(winRmTool, "echo myline");
assertSucceeded("echo myline", response, "myline", "", stopwatch);
stopwatch = Stopwatch.createStarted();
- WinRmToolResponse response2 = executePs(winRmTool, ImmutableList.of("echo myline"));
+ WinRmToolResponse response2 = executePs(winRmTool, "echo myline");
assertSucceeded("echo myline", response2, "myline", "", stopwatch);
}
@@ -397,7 +429,7 @@ public Void call() throws Exception {
String line = "myline" + makeRandomString(8);
Stopwatch stopwatch = Stopwatch.createStarted();
try {
- WinRmToolResponse response = executePs(winRmTool, ImmutableList.of("echo " + line));
+ WinRmToolResponse response = executePs(winRmTool, "echo " + line);
assertSucceeded("echo " + line, response, line, "", stopwatch);
LOG.info("Executed `echo "+line+"` in "+makeTimeStringRounded(stopwatch)+", in thread "+Thread.currentThread()+"; total "+counter.incrementAndGet()+" methods done");
return null;