Class: WinRM::CommandExecutor

Inherits:
Object
  • Object
show all
Defined in:
lib/winrm/command_executor.rb

Overview

Object which can execute multiple commands and Powershell scripts in one shared remote shell session. The maximum number of commands per shell is determined by interrogating the remote host when the session is opened and the remote shell is automatically recycled before the threshold is reached.

Author:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service) ⇒ CommandExecutor

Creates a CommandExecutor given a ‘WinRM::WinRMWebService` object.

Parameters:

  • service (WinRM::WinRMWebService)

    a winrm web service object responds to ‘#debug` and `#info` (default: `nil`)



54
55
56
57
58
# File 'lib/winrm/command_executor.rb', line 54

def initialize(service)
  @service = service
  @logger = service.logger
  @command_count = 0
end

Instance Attribute Details

#max_commandsInteger? (readonly)

Returns the safe maximum number of commands that can be executed in one remote shell session, or ‘nil` if the threshold has not yet been determined.

Returns:

  • (Integer, nil)

    the safe maximum number of commands that can be executed in one remote shell session, or ‘nil` if the threshold has not yet been determined



41
42
43
# File 'lib/winrm/command_executor.rb', line 41

def max_commands
  @max_commands
end

#serviceWinRM::WinRMWebService (readonly)

Returns a WinRM web service object.

Returns:



44
45
46
# File 'lib/winrm/command_executor.rb', line 44

def service
  @service
end

#shellString? (readonly)

Returns the identifier for the current open remote shell session, or ‘nil` if the session is not open.

Returns:

  • (String, nil)

    the identifier for the current open remote shell session, or ‘nil` if the session is not open



48
49
50
# File 'lib/winrm/command_executor.rb', line 48

def shell
  @shell
end

Class Method Details

.finalize(shell_id, service) ⇒ Object

Closes an open remote shell session left open after a command executor is garbage collecyted.

Parameters:

  • shell_id (String)

    the remote shell identifier

  • service (WinRM::WinRMWebService)

    a winrm web service object



34
35
36
# File 'lib/winrm/command_executor.rb', line 34

def self.finalize(shell_id, service)
  proc { service.close_shell(shell_id) }
end

Instance Method Details

#closeObject

Closes the open remote shell session. This method can be called multiple times, even if there is no open session.



62
63
64
65
66
67
68
# File 'lib/winrm/command_executor.rb', line 62

def close
  return if shell.nil?

  service.close_shell(shell)
  remove_finalizer
  @shell = nil
end

#openString

Opens a remote shell session for reuse. The maxiumum command-per-shell threshold is also determined the first time this method is invoked and cached for later invocations.

Returns:

  • (String)

    the remote shell session indentifier



75
76
77
78
79
80
81
82
# File 'lib/winrm/command_executor.rb', line 75

def open
  close
  retryable(service.retry_limit, service.retry_delay) { @shell = service.open_shell }
  add_finalizer(shell)
  @command_count = 0
  determine_max_commands unless max_commands
  shell
end

#run_cmd(command, arguments = []) {|stdout, stderr| ... } ⇒ WinRM::Output

Runs a CMD command.

Parameters:

  • command (String)

    the command to run on the remote system

  • arguments (Array<String>) (defaults to: [])

    arguments to the command

Yields:

  • (stdout, stderr)

    yields more live access the standard output and standard error streams as they are returns, if streaming behavior is desired

Returns:

  • (WinRM::Output)

    output object with stdout, stderr, and exit code



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/winrm/command_executor.rb', line 93

def run_cmd(command, arguments = [], &block)
  reset if command_count_exceeded?
  ensure_open_shell!

  @command_count += 1
  result = nil
  service.run_command(shell, command, arguments) do |command_id|
    result = service.get_command_output(shell, command_id, &block)
  end
  result
end

#run_powershell_script(script_file) {|stdout, stderr| ... } ⇒ WinRM::Output

Run a Powershell script that resides on the local box.

Parameters:

  • script_file (IO, String)

    an IO reference for reading the Powershell script or the actual file contents

Yields:

  • (stdout, stderr)

    yields more live access the standard output and standard error streams as they are returns, if streaming behavior is desired

Returns:

  • (WinRM::Output)

    output object with stdout, stderr, and exit code



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/winrm/command_executor.rb', line 114

def run_powershell_script(script_file, &block)
  # this code looks overly compact in an attempt to limit local
  # variable assignments that may contain large strings and
  # consequently bloat the Ruby VM
  run_cmd(
    'powershell',
    [
      '-encodedCommand',
      ::WinRM::PowershellScript.new(
        safe_script(script_file.is_a?(IO) ? script_file.read : script_file)
      ).encoded
    ],
    &block
  )
end