Class: WinRM::Shells::Powershell

Inherits:
Base
  • Object
show all
Includes:
WSMV::SOAP
Defined in:
lib/winrm/shells/power_shell.rb

Overview

Proxy to a remote PowerShell instance

Constant Summary

Constants included from WSMV::SOAP

WSMV::SOAP::NS_ADDRESSING, WSMV::SOAP::NS_CIMBINDING, WSMV::SOAP::NS_ENUM, WSMV::SOAP::NS_SCHEMA_INST, WSMV::SOAP::NS_SOAP_ENV, WSMV::SOAP::NS_TRANSFER, WSMV::SOAP::NS_WIN_SHELL, WSMV::SOAP::NS_WSMAN_CONF, WSMV::SOAP::NS_WSMAN_DMTF, WSMV::SOAP::NS_WSMAN_FAULT, WSMV::SOAP::NS_WSMAN_MSFT

Constants inherited from Base

Base::ERROR_OPERATION_ABORTED, Base::FAULTS_FOR_RESET, Base::SHELL_NOT_FOUND, Base::TOO_MANY_COMMANDS

Constants included from Retryable

Retryable::RETRYABLE_EXCEPTIONS

Instance Attribute Summary

Attributes inherited from Base

#connection_opts, #logger, #shell_id, #shell_opts, #shell_uri, #transport

Class Method Summary collapse

Instance Method Summary collapse

Methods included from WSMV::SOAP

#namespaces

Methods inherited from Base

#close, #run

Methods included from Retryable

#retryable

Constructor Details

#initialize(connection_opts, transport, logger) ⇒ Powershell

Create a new powershell shell

Parameters:

  • connection_opts (ConnectionOpts)

    The WinRM connection options

  • transport (HttpTransport)

    The WinRM SOAP transport

  • logger (Logger)

    The logger to log diagnostic messages to


50
51
52
53
# File 'lib/winrm/shells/power_shell.rb', line 50

def initialize(connection_opts, transport, logger)
  super
  @shell_uri = WinRM::WSMV::Header::RESOURCE_URI_POWERSHELL
end

Class Method Details

.close_shell(connection_opts, transport, shell_id) ⇒ Object


36
37
38
39
40
41
42
43
# File 'lib/winrm/shells/power_shell.rb', line 36

def close_shell(connection_opts, transport, shell_id)
  msg = WinRM::WSMV::CloseShell.new(
    connection_opts,
    shell_id: shell_id,
    shell_uri: WinRM::WSMV::Header::RESOURCE_URI_POWERSHELL
  )
  transport.send_request(msg.build)
end

.finalize(connection_opts, transport, shell_id) ⇒ Object


32
33
34
# File 'lib/winrm/shells/power_shell.rb', line 32

def finalize(connection_opts, transport, shell_id)
  proc { Powershell.close_shell(connection_opts, transport, shell_id) }
end

Instance Method Details

#max_fragment_blob_sizeObject

calculate the maimum fragment size so that they will be as large as possible yet no greater than the max_envelope_size_kb on the end point. To calculate this threshold, we:

  • determine the maximum number of bytes accepted on the endpoint

  • subtract the non-fragment characters in the SOAP envelope

  • determine the number of bytes that could be base64 encded to the above length

  • subtract the fragment header bytes (ids, length, etc)


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/winrm/shells/power_shell.rb', line 73

def max_fragment_blob_size
  @max_fragment_blob_size ||= begin
    fragment_header_length = 21

    begin
      max_fragment_bytes = (max_envelope_size_kb * 1024) - empty_pipeline_envelope.length
      base64_deflated(max_fragment_bytes) - fragment_header_length
    rescue WinRMWSManFault => e
      # A non administrator user will encounter an access denied
      # error attempting to query winrm configuration.
      # we will assin a small default and adjust to a protocol
      # appropriate max length when that info is available
      raise unless e.fault_code == '5'

      WinRM::PSRP::MessageFragmenter::DEFAULT_BLOB_LENGTH
    rescue WinRMSoapFault
      WinRM::PSRP::MessageFragmenter::DEFAULT_BLOB_LENGTH
    end
  end
end

#send_pipeline_command(command, &block) {|Message| ... } ⇒ Object

Runs the specified command

Parameters:

  • command (String)

    The powershell script to run

  • block (&block)

    The optional callback for any realtime output

Yields:

  • (Message)

    PSRP Message in response

Yield Returns:

  • (Array<Message>)

    All messages in response


60
61
62
63
64
# File 'lib/winrm/shells/power_shell.rb', line 60

def send_pipeline_command(command, &block)
  with_command_shell(command) do |shell, cmd|
    response_reader.read_message(command_output_message(shell, cmd), true, &block)
  end
end