diff --git a/powershell.go b/powershell.go index fd19639..58ec13e 100644 --- a/powershell.go +++ b/powershell.go @@ -2,13 +2,28 @@ package winrm import ( "encoding/base64" + "fmt" + "strings" "golang.org/x/text/encoding/unicode" ) +// PowershellOptions are options are passed to powershell.exe when executing a command +type PowershellOptions struct { + NoProfile bool + OutputFormat string +} + // Powershell wraps a PowerShell script // and prepares it for execution by the winrm client func Powershell(psCmd string) string { + return PowershellWithOptions(psCmd, PowershellOptions{}) +} + +// PowershellWithOptions wraps a PowerShell script +// and prepares it for execution by the winrm client. Depending on the values of the +// PowershellOptions struct the rrelevant switches are set before calling powershell.exe +func PowershellWithOptions(psCmd string, psOpts PowershellOptions) string { // Disable unnecessary progress bars which considered as stderr. psCmd = "$ProgressPreference = 'SilentlyContinue';" + psCmd @@ -22,6 +37,14 @@ func Powershell(psCmd string) string { // Finally make it base64 encoded which is required for powershell. psCmd = base64.StdEncoding.EncodeToString([]byte(encoded)) - // Specify powershell.exe to run encoded command - return "powershell.exe -EncodedCommand " + psCmd + cmds := []string{"powershell.exe"} + if psOpts.NoProfile { + cmds = append(cmds, "-NoProfile") + } + if psOpts.OutputFormat != "" { + cmds = append(cmds, fmt.Sprintf("-OutputFormat %s", psOpts.OutputFormat)) + } + cmds = append(cmds, fmt.Sprintf("-EncodedCommand %s", psCmd)) + + return strings.Join(cmds, " ") } diff --git a/powershell_test.go b/powershell_test.go index e387fe2..eda302e 100644 --- a/powershell_test.go +++ b/powershell_test.go @@ -4,7 +4,37 @@ import ( . "gopkg.in/check.v1" ) +const ( + plainTestCmd = "dir" + encodedTestCmd = "JABQAHIAbwBnAHIAZQBzAHMAUAByAGUAZgBlAHIAZQBuAGMAZQAgAD0AIAAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwA7AGQAaQByAA==" +) + func (s *WinRMSuite) TestPowershell(c *C) { - psCmd := Powershell("dir") - c.Assert(psCmd, Equals, "powershell.exe -EncodedCommand JABQAHIAbwBnAHIAZQBzAHMAUAByAGUAZgBlAHIAZQBuAGMAZQAgAD0AIAAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwA7AGQAaQByAA==") + psCmd := Powershell(plainTestCmd) + c.Assert(psCmd, Equals, "powershell.exe -EncodedCommand "+encodedTestCmd) +} + +func (s *WinRMSuite) TestPowershellWithNoProfile(c *C) { + testOpts := PowershellOptions{ + NoProfile: true, + } + psCmd := PowershellWithOptions(plainTestCmd, testOpts) + c.Assert(psCmd, Equals, "powershell.exe -NoProfile -EncodedCommand "+encodedTestCmd) +} + +func (s *WinRMSuite) TestPowershellWithOutputFormat(c *C) { + testOpts := PowershellOptions{ + OutputFormat: "Text", + } + psCmd := PowershellWithOptions(plainTestCmd, testOpts) + c.Assert(psCmd, Equals, "powershell.exe -OutputFormat Text -EncodedCommand "+encodedTestCmd) +} + +func (s *WinRMSuite) TestPowershellWithAllOptions(c *C) { + testOpts := PowershellOptions{ + OutputFormat: "Text", + NoProfile: true, + } + psCmd := PowershellWithOptions(plainTestCmd, testOpts) + c.Assert(psCmd, Equals, "powershell.exe -NoProfile -OutputFormat Text -EncodedCommand "+encodedTestCmd) }