powershell.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // +build windows
  2. // Copyright 2015 flannel authors
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. package powershell
  16. import (
  17. "encoding/json"
  18. "errors"
  19. "fmt"
  20. "os/exec"
  21. "strings"
  22. )
  23. //commandWrapper ensures that exceptions are written to stdout and the powershell process exit code is -1
  24. const commandWrapper = `$ErrorActionPreference="Stop";try { %s } catch { Write-Host $_; os.Exit(-1) }`
  25. // RunCommand executes a given powershell command.
  26. //
  27. // When the command throws a powershell exception, RunCommand will return the exception message as error.
  28. func RunCommand(command string) ([]byte, error) {
  29. cmd := exec.Command("powershell.exe", "-NoLogo", "-NoProfile", "-NonInteractive", "-Command", fmt.Sprintf(commandWrapper, command))
  30. stdout, err := cmd.Output()
  31. if err != nil {
  32. if cmd.ProcessState.ExitCode() != 0 {
  33. message := strings.TrimSpace(string(stdout))
  34. return []byte{}, errors.New(message)
  35. }
  36. return []byte{}, err
  37. }
  38. return stdout, nil
  39. }
  40. // RunCommandf executes a given powershell command. Command argument formats according to a format specifier (See fmt.Sprintf).
  41. //
  42. // When the command throws a powershell exception, RunCommandf will return the exception message as error.
  43. func RunCommandf(command string, a ...interface{}) ([]byte, error) {
  44. return RunCommand(fmt.Sprintf(command, a...))
  45. }
  46. // RunCommandWithJsonResult executes a given powershell command.
  47. // The command will be wrapped with ConvertTo-Json.
  48. //
  49. // You can Wrap your command with @(<cmd>) to ensure that the returned json is an array
  50. //
  51. // When the command throws a powershell exception, RunCommandf will return the exception message as error.
  52. func RunCommandWithJsonResult(command string, v interface{}) error {
  53. wrappedCommand := fmt.Sprintf(commandWrapper, "ConvertTo-Json (%s)")
  54. wrappedCommand = fmt.Sprintf(wrappedCommand, command)
  55. stdout, err := RunCommandf(wrappedCommand)
  56. if err != nil {
  57. return err
  58. }
  59. err = json.Unmarshal(stdout, v)
  60. if err != nil {
  61. return err
  62. }
  63. return nil
  64. }