class WinRM::WinRMWebService

This is the main class that does the SOAP request/response logic. There are a few helper classes, but pretty much everything comes through here first.

Constants

DEFAULT_LOCALE
DEFAULT_MAX_ENV_SIZE
DEFAULT_TIMEOUT

Attributes

endpoint[R]
timeout[R]

Public Class Methods

new(endpoint, transport = :kerberos, opts = {}) click to toggle source

@param [String,URI] endpoint the WinRM webservice endpoint @param [Symbol] transport either :kerberos(default)/:ssl/:plaintext @param [Hash] opts Misc opts for the various transports.

@see WinRM::HTTP::HttpTransport
@see WinRM::HTTP::HttpGSSAPI
@see WinRM::HTTP::HttpSSL
# File lib/winrm/winrm_service.rb, line 36
def initialize(endpoint, transport = :kerberos, opts = {})
  @endpoint = endpoint
  @timeout = DEFAULT_TIMEOUT
  @max_env_sz = DEFAULT_MAX_ENV_SIZE
  @locale = DEFAULT_LOCALE
  @logger = Logging.logger[self]
  case transport
  when :kerberos
    require 'gssapi'
    require 'gssapi/extensions'
    @xfer = HTTP::HttpGSSAPI.new(endpoint, opts[:realm], opts[:service], opts[:keytab], opts)
  when :plaintext
    @xfer = HTTP::HttpPlaintext.new(endpoint, opts[:user], opts[:pass], opts)
  when :ssl
    @xfer = HTTP::HttpSSL.new(endpoint, opts[:user], opts[:pass], opts[:ca_trust_path], opts)
  else
    raise "Invalid transport '#{transport}' specified, expected: kerberos, plaintext, ssl."
  end
end

Public Instance Methods

cleanup_command(shell_id, command_id) click to toggle source

Clean-up after a command. @see run_command @param [String] shell_id The shell id on the remote machine. See open_shell @param [String] command_id The command id on the remote machine. See run_command @return [true] This should have more error checking but it just returns true for now.

# File lib/winrm/winrm_service.rb, line 260
def cleanup_command(shell_id, command_id)
  # Signal the Command references to terminate (close stdout/stderr)
  body = { "#{NS_WIN_SHELL}:Code" => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/signal/terminate' }
  builder = Builder::XmlMarkup.new
  builder.instruct!(:xml, :encoding => 'UTF-8')
  builder.tag! :env, :Envelope, namespaces do |env|
    env.tag!(:env, :Header) { |h| h << Gyoku.xml(merge_headers(header,resource_uri_cmd,action_signal,selector_shell_id(shell_id))) }
    env.tag!(:env, :Body) do |env_body|
      env_body.tag!("#{NS_WIN_SHELL}:Signal", {'CommandId' => command_id}) { |cl| cl << Gyoku.xml(body) }
    end
  end
  resp = send_message(builder.target!)
  true
end
close_shell(shell_id) click to toggle source

Close the shell @param [String] shell_id The shell id on the remote machine. See open_shell @return [true] This should have more error checking but it just returns true for now.

# File lib/winrm/winrm_service.rb, line 278
def close_shell(shell_id)
  builder = Builder::XmlMarkup.new
  builder.instruct!(:xml, :encoding => 'UTF-8')

  builder.tag!('env:Envelope', namespaces) do |env|
    env.tag!('env:Header') { |h| h << Gyoku.xml(merge_headers(header,resource_uri_cmd,action_delete,selector_shell_id(shell_id))) }
    env.tag!('env:Body')
  end

  resp = send_message(builder.target!)
  true
end
cmd(command, arguments = [], &block)
Alias for: run_cmd
get_command_output(shell_id, command_id) { |stream, stream| ... } click to toggle source

Get the Output of the given shell and command @param [String] shell_id The shell id on the remote machine. See open_shell @param [String] command_id The command id on the remote machine. See run_command @return [Hash] Returns a Hash with a key :exitcode and :data. Data is an Array of Hashes where the cooresponding key

is either :stdout or :stderr.  The reason it is in an Array so so we can get the output in the order it ocurrs on
the console.
# File lib/winrm/winrm_service.rb, line 211
def get_command_output(shell_id, command_id, &block)
  body = { "#{NS_WIN_SHELL}:DesiredStream" => 'stdout stderr',
    :attributes! => {"#{NS_WIN_SHELL}:DesiredStream" => {'CommandId' => command_id}}}

  builder = Builder::XmlMarkup.new
  builder.instruct!(:xml, :encoding => 'UTF-8')
  builder.tag! :env, :Envelope, namespaces do |env|
    env.tag!(:env, :Header) { |h| h << Gyoku.xml(merge_headers(header,resource_uri_cmd,action_receive,selector_shell_id(shell_id))) }
    env.tag!(:env, :Body) do |env_body|
      env_body.tag!("#{NS_WIN_SHELL}:Receive") { |cl| cl << Gyoku.xml(body) }
    end
  end

  resp_doc = nil
  request_msg = builder.target!
  done_elems = []
  output = Output.new

  while done_elems.empty?
    resp_doc = send_get_output_message(request_msg)

    REXML::XPath.match(resp_doc, "//#{NS_WIN_SHELL}:Stream").each do |n|
      next if n.text.nil? || n.text.empty?
      stream = { n.attributes['Name'].to_sym => Base64.decode64(n.text) }
      output[:data] << stream
      yield stream[:stdout], stream[:stderr] if block_given?
    end

    # We may need to get additional output if the stream has not finished.
    # The CommandState will change from Running to Done like so:
    # @example
    #   from...
    #   <rsp:CommandState CommandId="..." State="http://schemas.microsoft.com/wbem/wsman/1/windows/shell/CommandState/Running"/>
    #   to...
    #   <rsp:CommandState CommandId="..." State="http://schemas.microsoft.com/wbem/wsman/1/windows/shell/CommandState/Done">
    #     <rsp:ExitCode>0</rsp:ExitCode>
    #   </rsp:CommandState>
    done_elems = REXML::XPath.match(resp_doc, "//*[@State='http://schemas.microsoft.com/wbem/wsman/1/windows/shell/CommandState/Done']")
  end

  output[:exitcode] = REXML::XPath.first(resp_doc, "//#{NS_WIN_SHELL}:ExitCode").text.to_i
  output
end
locale(locale) click to toggle source

Set the locale @see msdn.microsoft.com/en-us/library/gg567404(v=PROT.13).aspx @param [String] locale the locale to set for future messages

# File lib/winrm/winrm_service.rb, line 83
def locale(locale)
  @locale = locale
end
max_env_size(byte_sz) click to toggle source

Max envelope size @see msdn.microsoft.com/en-us/library/ee916127(v=PROT.13).aspx @param [Fixnum] byte_sz the max size in bytes to allow for the response

# File lib/winrm/winrm_service.rb, line 76
def max_env_size(byte_sz)
  @max_env_sz = byte_sz
end
op_timeout(op_timeout_sec, receive_timeout_sec=nil)
Alias for: set_timeout
open_shell(shell_opts = {}) { |shell_id| ... } click to toggle source

Create a Shell on the destination host @param [Hash<optional>] shell_opts additional shell options you can pass @option shell_opts [String] :i_stream Which input stream to open. Leave this alone unless you know what you're doing (default: stdin) @option shell_opts [String] :o_stream Which output stream to open. Leave this alone unless you know what you're doing (default: stdout stderr) @option shell_opts [String] :working_directory the directory to create the shell in @option shell_opts [Hash] :env_vars environment variables to set for the shell. For instance;

:env_vars => {:myvar1 => 'val1', :myvar2 => 'var2'}

@return [String] The ShellId from the SOAP response. This is our open shell instance on the remote machine.

# File lib/winrm/winrm_service.rb, line 95
def open_shell(shell_opts = {}, &block)
  i_stream = shell_opts.has_key?(:i_stream) ? shell_opts[:i_stream] : 'stdin'
  o_stream = shell_opts.has_key?(:o_stream) ? shell_opts[:o_stream] : 'stdout stderr'
  codepage = shell_opts.has_key?(:codepage) ? shell_opts[:codepage] : 437
  noprofile = shell_opts.has_key?(:noprofile) ? shell_opts[:noprofile] : 'FALSE'
  h_opts = { "#{NS_WSMAN_DMTF}:OptionSet" => { "#{NS_WSMAN_DMTF}:Option" => [noprofile, codepage],
    :attributes! => {"#{NS_WSMAN_DMTF}:Option" => {'Name' => ['WINRS_NOPROFILE','WINRS_CODEPAGE']}}}}
  shell_body = {
    "#{NS_WIN_SHELL}:InputStreams" => i_stream,
    "#{NS_WIN_SHELL}:OutputStreams" => o_stream
  }
  shell_body["#{NS_WIN_SHELL}:WorkingDirectory"] = shell_opts[:working_directory] if shell_opts.has_key?(:working_directory)
  shell_body["#{NS_WIN_SHELL}:IdleTimeOut"] = shell_opts[:idle_timeout] if(shell_opts.has_key?(:idle_timeout) && shell_opts[:idle_timeout].is_a?(String))
  if(shell_opts.has_key?(:env_vars) && shell_opts[:env_vars].is_a?(Hash))
    keys = shell_opts[:env_vars].keys
    vals = shell_opts[:env_vars].values
    shell_body["#{NS_WIN_SHELL}:Environment"] = {
      "#{NS_WIN_SHELL}:Variable" => vals,
      :attributes! => {"#{NS_WIN_SHELL}:Variable" => {'Name' => keys}}
    }
  end
  builder = Builder::XmlMarkup.new
  builder.instruct!(:xml, :encoding => 'UTF-8')
  builder.tag! :env, :Envelope, namespaces do |env|
    env.tag!(:env, :Header) { |h| h << Gyoku.xml(merge_headers(header,resource_uri_cmd,action_create,h_opts)) }
    env.tag! :env, :Body do |body|
      body.tag!("#{NS_WIN_SHELL}:Shell") { |s| s << Gyoku.xml(shell_body)}
    end
  end

  resp_doc = send_message(builder.target!)
  shell_id = REXML::XPath.first(resp_doc, "//*[@Name='ShellId']").text

  if block_given?
    begin
      yield shell_id
    ensure
      close_shell(shell_id)
    end
  else
    shell_id
  end
end
powershell(script_file, &block)
run_cmd(command, arguments = [], &block) click to toggle source

Run a CMD command @param [String] command The command to run on the remote system @param [Array <String>] arguments arguments to the command @param [String] an existing and open shell id to reuse @return [Hash] :stdout and :stderr

# File lib/winrm/winrm_service.rb, line 296
def run_cmd(command, arguments = [], &block)
  command_output = nil
  open_shell do |shell_id|
    run_command(shell_id, command, arguments) do |command_id|
      command_output = get_command_output(shell_id, command_id, &block)
    end
  end
  command_output
end
Also aliased as: cmd
run_command(shell_id, command, arguments = [], cmd_opts = {}) { |command_id| ... } click to toggle source

Run a command on a machine with an open shell @param [String] shell_id The shell id on the remote machine. See open_shell @param [String] command The command to run on the remote machine @param [Array<String>] arguments An array of arguments for this command @return [String] The CommandId from the SOAP response. This is the ID we need to query in order to get output.

# File lib/winrm/winrm_service.rb, line 144
def run_command(shell_id, command, arguments = [], cmd_opts = {}, &block)
  consolemode = cmd_opts.has_key?(:console_mode_stdin) ? cmd_opts[:console_mode_stdin] : 'TRUE'
  skipcmd     = cmd_opts.has_key?(:skip_cmd_shell) ? cmd_opts[:skip_cmd_shell] : 'FALSE'

  h_opts = { "#{NS_WSMAN_DMTF}:OptionSet" => {
    "#{NS_WSMAN_DMTF}:Option" => [consolemode, skipcmd],
    :attributes! => {"#{NS_WSMAN_DMTF}:Option" => {'Name' => ['WINRS_CONSOLEMODE_STDIN','WINRS_SKIP_CMD_SHELL']}}}
  }
  body = { "#{NS_WIN_SHELL}:Command" => "\"#{command}\"", "#{NS_WIN_SHELL}:Arguments" => arguments}

  builder = Builder::XmlMarkup.new
  builder.instruct!(:xml, :encoding => 'UTF-8')
  builder.tag! :env, :Envelope, namespaces do |env|
    env.tag!(:env, :Header) { |h| h << Gyoku.xml(merge_headers(header,resource_uri_cmd,action_command,h_opts,selector_shell_id(shell_id))) }
    env.tag!(:env, :Body) do |env_body|
      env_body.tag!("#{NS_WIN_SHELL}:CommandLine") { |cl| cl << Gyoku.xml(body) }
    end
  end

  # Grab the command element and unescape any single quotes - issue 69
  xml = builder.target!
  escaped_cmd = /<#{NS_WIN_SHELL}:Command>(.+)<\/#{NS_WIN_SHELL}:Command>/m.match(xml)[1]
  xml[escaped_cmd] = escaped_cmd.gsub(/&#39;/, "'")

  resp_doc = send_message(xml)
  command_id = REXML::XPath.first(resp_doc, "//#{NS_WIN_SHELL}:CommandId").text

  if block_given?
    begin
      yield command_id
    ensure
      cleanup_command(shell_id, command_id)
    end
  else
    command_id
  end
end
run_powershell_script(script_file, &block) click to toggle source

Run a Powershell script that resides on the local box. @param [IO,String] script_file an IO reference for reading the Powershell script or the actual file contents @param [String] an existing and open shell id to reuse @return [Hash] :stdout and :stderr

# File lib/winrm/winrm_service.rb, line 312
def run_powershell_script(script_file, &block)
  # if an IO object is passed read it..otherwise assume the contents of the file were passed
  script_text = script_file.respond_to?(:read) ? script_file.read : script_file
  script = WinRM::PowershellScript.new(script_text)
  run_cmd("powershell -encodedCommand #{script.encoded()}", &block)
end
Also aliased as: powershell
run_wql(wql) click to toggle source

Run a WQL Query @see msdn.microsoft.com/en-us/library/aa394606(VS.85).aspx @param [String] wql The WQL query @return [Hash] Returns a Hash that contain the key/value pairs returned from the query.

# File lib/winrm/winrm_service.rb, line 325
def run_wql(wql)

  body = { "#{NS_WSMAN_DMTF}:OptimizeEnumeration" => nil,
    "#{NS_WSMAN_DMTF}:MaxElements" => '32000',
    "#{NS_WSMAN_DMTF}:Filter" => wql,
    :attributes! => { "#{NS_WSMAN_DMTF}:Filter" => {'Dialect' => 'http://schemas.microsoft.com/wbem/wsman/1/WQL'}}
  }

  builder = Builder::XmlMarkup.new
  builder.instruct!(:xml, :encoding => 'UTF-8')
  builder.tag! :env, :Envelope, namespaces do |env|
    env.tag!(:env, :Header) { |h| h << Gyoku.xml(merge_headers(header,resource_uri_wmi,action_enumerate)) }
    env.tag!(:env, :Body) do |env_body|
      env_body.tag!("#{NS_ENUM}:Enumerate") { |en| en << Gyoku.xml(body) }
    end
  end

  resp = send_message(builder.target!)
  parser = Nori.new(:parser => :rexml, :advanced_typecasting => false, :convert_tags_to => lambda { |tag| tag.snakecase.to_sym }, :strip_namespaces => true)
  hresp = parser.parse(resp.to_s)[:envelope][:body]
  
  # Normalize items so the type always has an array even if it's just a single item.
  items = {}
  if hresp[:enumerate_response][:items]
    hresp[:enumerate_response][:items].each_pair do |k,v|
      if v.is_a?(Array)
        items[k] = v
      else
        items[k] = [v]
      end
    end
  end
  items
end
Also aliased as: wql
set_timeout(op_timeout_sec, receive_timeout_sec=nil) click to toggle source

Operation timeout.

Unless specified the client receive timeout will be 10s + the operation timeout.

@see msdn.microsoft.com/en-us/library/ee916629(v=PROT.13).aspx

@param [Fixnum] The number of seconds to set the WinRM operation timeout @param [Fixnum] The number of seconds to set the Ruby receive timeout @return [String] The ISO 8601 formatted operation timeout

# File lib/winrm/winrm_service.rb, line 66
def set_timeout(op_timeout_sec, receive_timeout_sec=nil)
  @timeout = Iso8601Duration.sec_to_dur(op_timeout_sec)
  @xfer.receive_timeout = receive_timeout_sec || op_timeout_sec + 10
  @timeout
end
Also aliased as: op_timeout
toggle_nori_type_casting(to) click to toggle source
# File lib/winrm/winrm_service.rb, line 361
def toggle_nori_type_casting(to)
  @logger.warn('toggle_nori_type_casting is deprecated and has no effect, ' +
    'please remove calls to it')
end
wql(wql)
Alias for: run_wql
write_stdin(shell_id, command_id, stdin) click to toggle source
# File lib/winrm/winrm_service.rb, line 182
def write_stdin(shell_id, command_id, stdin)
  # Signal the Command references to terminate (close stdout/stderr)
  body = {
    "#{NS_WIN_SHELL}:Send" => {
      "#{NS_WIN_SHELL}:Stream" => {
        "@Name" => 'stdin',
        "@CommandId" => command_id,
        :content! => Base64.encode64(stdin)
      }
    }
  }
  builder = Builder::XmlMarkup.new
  builder.instruct!(:xml, :encoding => 'UTF-8')
  builder.tag! :env, :Envelope, namespaces do |env|
    env.tag!(:env, :Header) { |h| h << Gyoku.xml(merge_headers(header,resource_uri_cmd,action_send,selector_shell_id(shell_id))) }
    env.tag!(:env, :Body) do |env_body|
      env_body << Gyoku.xml(body)
    end
  end
  resp = send_message(builder.target!)
  true
end

Private Instance Methods

action_command() click to toggle source
# File lib/winrm/winrm_service.rb, line 455
def action_command
  {"#{NS_ADDRESSING}:Action" => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Command',
    :attributes! => {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => true}}}
end
action_create() click to toggle source
# File lib/winrm/winrm_service.rb, line 445
def action_create
  {"#{NS_ADDRESSING}:Action" => 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Create',
    :attributes! => {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => true}}}
end
action_delete() click to toggle source
# File lib/winrm/winrm_service.rb, line 450
def action_delete
  {"#{NS_ADDRESSING}:Action" => 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete',
    :attributes! => {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => true}}}
end
action_enumerate() click to toggle source
# File lib/winrm/winrm_service.rb, line 475
def action_enumerate
  {"#{NS_ADDRESSING}:Action" => 'http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate',
    :attributes! => {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => true}}}
end
action_receive() click to toggle source
# File lib/winrm/winrm_service.rb, line 460
def action_receive
  {"#{NS_ADDRESSING}:Action" => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive',
    :attributes! => {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => true}}}
end
action_send() click to toggle source
# File lib/winrm/winrm_service.rb, line 470
def action_send
  {"#{NS_ADDRESSING}:Action" => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Send',
    :attributes! => {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => true}}}
end
action_signal() click to toggle source
# File lib/winrm/winrm_service.rb, line 465
def action_signal
  {"#{NS_ADDRESSING}:Action" => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Signal',
    :attributes! => {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => true}}}
end
header() click to toggle source
# File lib/winrm/winrm_service.rb, line 384
def header
  { "#{NS_ADDRESSING}:To" => "#{@xfer.endpoint.to_s}",
    "#{NS_ADDRESSING}:ReplyTo" => {
    "#{NS_ADDRESSING}:Address" => 'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous',
      :attributes! => {"#{NS_ADDRESSING}:Address" => {'mustUnderstand' => true}}},
    "#{NS_WSMAN_DMTF}:MaxEnvelopeSize" => @max_env_sz,
    "#{NS_ADDRESSING}:MessageID" => "uuid:#{UUIDTools::UUID.random_create.to_s.upcase}",
    "#{NS_WSMAN_DMTF}:Locale/" => '',
    "#{NS_WSMAN_MSFT}:DataLocale/" => '',
    "#{NS_WSMAN_DMTF}:OperationTimeout" => @timeout,
    :attributes! => {
      "#{NS_WSMAN_DMTF}:MaxEnvelopeSize" => {'mustUnderstand' => true},
      "#{NS_WSMAN_DMTF}:Locale/" => {'xml:lang' => @locale, 'mustUnderstand' => false},
      "#{NS_WSMAN_MSFT}:DataLocale/" => {'xml:lang' => @locale, 'mustUnderstand' => false}
    }}
end
merge_headers(*headers) click to toggle source

merge the various header hashes and make sure we carry all of the attributes

through instead of overwriting them.
# File lib/winrm/winrm_service.rb, line 403
def merge_headers(*headers)
  hdr = {}
  headers.each do |h|
    hdr.merge!(h) do |k,v1,v2|
      v1.merge!(v2) if k == :attributes!
    end
  end
  hdr
end
namespaces() click to toggle source
# File lib/winrm/winrm_service.rb, line 368
def namespaces
  {
    'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
    'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
    'xmlns:env' => 'http://www.w3.org/2003/05/soap-envelope',
    'xmlns:a' => 'http://schemas.xmlsoap.org/ws/2004/08/addressing',
    'xmlns:b' => 'http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd',
    'xmlns:n' => 'http://schemas.xmlsoap.org/ws/2004/09/enumeration',
    'xmlns:x' => 'http://schemas.xmlsoap.org/ws/2004/09/transfer',
    'xmlns:w' => 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd',
    'xmlns:p' => 'http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd',
    'xmlns:rsp' => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell',
    'xmlns:cfg' => 'http://schemas.microsoft.com/wbem/wsman/1/config',
  }
end
resource_uri_cmd() click to toggle source

Helper methods for SOAP Headers

# File lib/winrm/winrm_service.rb, line 435
def resource_uri_cmd
  {"#{NS_WSMAN_DMTF}:ResourceURI" => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd',
    :attributes! => {"#{NS_WSMAN_DMTF}:ResourceURI" => {'mustUnderstand' => true}}}
end
resource_uri_wmi(namespace = 'root/cimv2/*') click to toggle source
# File lib/winrm/winrm_service.rb, line 440
def resource_uri_wmi(namespace = 'root/cimv2/*')
  {"#{NS_WSMAN_DMTF}:ResourceURI" => "http://schemas.microsoft.com/wbem/wsman/1/wmi/#{namespace}",
    :attributes! => {"#{NS_WSMAN_DMTF}:ResourceURI" => {'mustUnderstand' => true}}}
end
selector_shell_id(shell_id) click to toggle source
# File lib/winrm/winrm_service.rb, line 480
def selector_shell_id(shell_id)
  {"#{NS_WSMAN_DMTF}:SelectorSet" =>
    {"#{NS_WSMAN_DMTF}:Selector" => shell_id, :attributes! => {"#{NS_WSMAN_DMTF}:Selector" => {'Name' => 'ShellId'}}}
  }
end
send_get_output_message(message) click to toggle source
# File lib/winrm/winrm_service.rb, line 413
def send_get_output_message(message)
  send_message(message)
rescue WinRMWSManFault => e
  # If no output is available before the wsman:OperationTimeout expires,
  # the server MUST return a WSManFault with the Code attribute equal to
  # 2150858793. When the client receives this fault, it SHOULD issue 
  # another Receive request.
  # http://msdn.microsoft.com/en-us/library/cc251676.aspx
  if e.fault_code == '2150858793'
    retry
  else
    raise
  end
end
send_message(message) click to toggle source
# File lib/winrm/winrm_service.rb, line 428
def send_message(message)
  @xfer.send_request(message)
end