winrm 2.2.3 → 2.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +1 -1
- data/bin/rwinrm +90 -97
- data/lib/winrm/connection.rb +84 -86
- data/lib/winrm/connection_opts.rb +90 -91
- data/lib/winrm/exceptions.rb +14 -2
- data/lib/winrm/http/response_handler.rb +127 -96
- data/lib/winrm/http/transport.rb +462 -427
- data/lib/winrm/http/transport_factory.rb +1 -5
- data/lib/winrm/output.rb +1 -2
- data/lib/winrm/psrp/fragment.rb +0 -2
- data/lib/winrm/psrp/message.rb +128 -130
- data/lib/winrm/psrp/message_data/base.rb +0 -2
- data/lib/winrm/psrp/message_data/error_record.rb +2 -2
- data/lib/winrm/psrp/message_data/pipeline_host_call.rb +0 -2
- data/lib/winrm/psrp/message_data/pipeline_output.rb +48 -54
- data/lib/winrm/psrp/message_data/pipeline_state.rb +0 -2
- data/lib/winrm/psrp/message_data/runspacepool_host_call.rb +0 -2
- data/lib/winrm/psrp/message_data/runspacepool_state.rb +0 -2
- data/lib/winrm/psrp/message_data/session_capability.rb +0 -2
- data/lib/winrm/psrp/message_data.rb +0 -2
- data/lib/winrm/psrp/message_defragmenter.rb +2 -2
- data/lib/winrm/psrp/message_factory.rb +16 -5
- data/lib/winrm/psrp/message_fragmenter.rb +1 -3
- data/lib/winrm/psrp/powershell_output_decoder.rb +142 -144
- data/lib/winrm/psrp/receive_response_reader.rb +3 -5
- data/lib/winrm/psrp/uuid.rb +1 -2
- data/lib/winrm/shells/base.rb +7 -4
- data/lib/winrm/shells/cmd.rb +63 -65
- data/lib/winrm/shells/power_shell.rb +207 -202
- data/lib/winrm/shells/retryable.rb +44 -45
- data/lib/winrm/shells/shell_factory.rb +0 -2
- data/lib/winrm/version.rb +1 -3
- data/lib/winrm/wsmv/base.rb +0 -2
- data/lib/winrm/wsmv/cleanup_command.rb +1 -2
- data/lib/winrm/wsmv/close_shell.rb +1 -2
- data/lib/winrm/wsmv/command.rb +2 -3
- data/lib/winrm/wsmv/command_output.rb +2 -3
- data/lib/winrm/wsmv/command_output_decoder.rb +1 -2
- data/lib/winrm/wsmv/configuration.rb +0 -2
- data/lib/winrm/wsmv/create_pipeline.rb +0 -2
- data/lib/winrm/wsmv/create_shell.rb +2 -6
- data/lib/winrm/wsmv/header.rb +213 -215
- data/lib/winrm/wsmv/init_runspace_pool.rb +96 -95
- data/lib/winrm/wsmv/iso8601_duration.rb +0 -2
- data/lib/winrm/wsmv/keep_alive.rb +0 -2
- data/lib/winrm/wsmv/receive_response_reader.rb +128 -126
- data/lib/winrm/wsmv/send_data.rb +0 -2
- data/lib/winrm/wsmv/soap.rb +0 -2
- data/lib/winrm/wsmv/wql_pull.rb +54 -56
- data/lib/winrm/wsmv/wql_query.rb +98 -99
- data/lib/winrm/wsmv/write_stdin.rb +0 -2
- data/lib/winrm.rb +3 -5
- metadata +81 -135
- data/.gitignore +0 -10
- data/.rubocop.yml +0 -26
- data/.travis.yml +0 -11
- data/Gemfile +0 -3
- data/Rakefile +0 -34
- data/Vagrantfile +0 -6
- data/WinrmAppveyor.psm1 +0 -32
- data/appveyor.yml +0 -51
- data/changelog.md +0 -128
- data/preamble +0 -17
- data/tests/integration/auth_timeout_spec.rb +0 -18
- data/tests/integration/cmd_spec.rb +0 -131
- data/tests/integration/config-example.yml +0 -16
- data/tests/integration/issue_59_spec.rb +0 -26
- data/tests/integration/powershell_spec.rb +0 -165
- data/tests/integration/spec_helper.rb +0 -65
- data/tests/integration/transport_spec.rb +0 -99
- data/tests/integration/wql_spec.rb +0 -34
- data/tests/matchers.rb +0 -60
- data/tests/spec/configuration_spec.rb +0 -184
- data/tests/spec/connection_spec.rb +0 -39
- data/tests/spec/exception_spec.rb +0 -50
- data/tests/spec/http/transport_factory_spec.rb +0 -68
- data/tests/spec/http/transport_spec.rb +0 -44
- data/tests/spec/output_spec.rb +0 -127
- data/tests/spec/psrp/fragment_spec.rb +0 -62
- data/tests/spec/psrp/message_data/base_spec.rb +0 -13
- data/tests/spec/psrp/message_data/error_record_spec.rb +0 -41
- data/tests/spec/psrp/message_data/pipeline_host_call_spec.rb +0 -25
- data/tests/spec/psrp/message_data/pipeline_output_spec.rb +0 -32
- data/tests/spec/psrp/message_data/pipeline_state_spec.rb +0 -40
- data/tests/spec/psrp/message_data/runspace_pool_host_call_spec.rb +0 -25
- data/tests/spec/psrp/message_data/runspacepool_state_spec.rb +0 -16
- data/tests/spec/psrp/message_data/session_capability_spec.rb +0 -30
- data/tests/spec/psrp/message_data_spec.rb +0 -35
- data/tests/spec/psrp/message_defragmenter_spec.rb +0 -47
- data/tests/spec/psrp/message_fragmenter_spec.rb +0 -105
- data/tests/spec/psrp/powershell_output_decoder_spec.rb +0 -100
- data/tests/spec/psrp/psrp_message_spec.rb +0 -70
- data/tests/spec/psrp/recieve_response_reader_spec.rb +0 -172
- data/tests/spec/psrp/uuid_spec.rb +0 -28
- data/tests/spec/response_handler_spec.rb +0 -61
- data/tests/spec/shells/base_spec.rb +0 -225
- data/tests/spec/shells/cmd_spec.rb +0 -75
- data/tests/spec/shells/powershell_spec.rb +0 -175
- data/tests/spec/spec_helper.rb +0 -47
- data/tests/spec/stubs/clixml/error_record.xml.erb +0 -84
- data/tests/spec/stubs/clixml/pipeline_state.xml.erb +0 -88
- data/tests/spec/stubs/responses/get_command_output_response.xml.erb +0 -13
- data/tests/spec/stubs/responses/get_command_output_response_not_done.xml.erb +0 -10
- data/tests/spec/stubs/responses/get_powershell_keepalive_response.xml.erb +0 -10
- data/tests/spec/stubs/responses/get_powershell_output_response.xml.erb +0 -12
- data/tests/spec/stubs/responses/get_powershell_output_response_not_done.xml.erb +0 -9
- data/tests/spec/stubs/responses/open_shell_v1.xml +0 -19
- data/tests/spec/stubs/responses/open_shell_v2.xml +0 -20
- data/tests/spec/stubs/responses/soap_fault_v1.xml +0 -36
- data/tests/spec/stubs/responses/soap_fault_v2.xml +0 -42
- data/tests/spec/stubs/responses/wmi_error_v2.xml +0 -41
- data/tests/spec/wsmv/cleanup_command_spec.rb +0 -22
- data/tests/spec/wsmv/close_shell_spec.rb +0 -17
- data/tests/spec/wsmv/command_output_decoder_spec.rb +0 -37
- data/tests/spec/wsmv/command_output_spec.rb +0 -45
- data/tests/spec/wsmv/command_spec.rb +0 -19
- data/tests/spec/wsmv/configuration_spec.rb +0 -17
- data/tests/spec/wsmv/create_pipeline_spec.rb +0 -31
- data/tests/spec/wsmv/create_shell_spec.rb +0 -38
- data/tests/spec/wsmv/init_runspace_pool_spec.rb +0 -36
- data/tests/spec/wsmv/keep_alive_spec.rb +0 -21
- data/tests/spec/wsmv/receive_response_reader_spec.rb +0 -123
- data/tests/spec/wsmv/send_data_spec.rb +0 -30
- data/tests/spec/wsmv/wql_query_spec.rb +0 -13
- data/tests/spec/wsmv/write_stdin_spec.rb +0 -22
- data/winrm.gemspec +0 -47
|
@@ -1,126 +1,128 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
require_relative '
|
|
18
|
-
require_relative '
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
@
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
#
|
|
41
|
-
# @
|
|
42
|
-
# @
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
#
|
|
55
|
-
# @
|
|
56
|
-
# @
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
logger.debug('[WinRM]
|
|
63
|
-
resp_doc
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
output
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
end
|
|
1
|
+
# Copyright 2016 Shawn Neal <sneal@sneal.net>
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
require_relative 'soap'
|
|
16
|
+
require_relative 'header'
|
|
17
|
+
require_relative 'command_output_decoder'
|
|
18
|
+
require_relative '../output'
|
|
19
|
+
|
|
20
|
+
module WinRM
|
|
21
|
+
module WSMV
|
|
22
|
+
# Class for reading wsmv Receive_Response messages
|
|
23
|
+
class ReceiveResponseReader
|
|
24
|
+
include WinRM::WSMV::SOAP
|
|
25
|
+
include WinRM::WSMV::Header
|
|
26
|
+
|
|
27
|
+
# Creates a new ReceiveResponseReader
|
|
28
|
+
# @param transport [HttpTransport] The WinRM SOAP transport
|
|
29
|
+
# @param logger [Logger] The logger to log diagnostic messages to
|
|
30
|
+
def initialize(transport, logger)
|
|
31
|
+
@transport = transport
|
|
32
|
+
@logger = logger
|
|
33
|
+
@output_decoder = CommandOutputDecoder.new
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
attr_reader :logger
|
|
37
|
+
|
|
38
|
+
# Reads streams and returns decoded output
|
|
39
|
+
# @param wsmv_message [WinRM::WSMV::Base] A wsmv message to send to endpoint
|
|
40
|
+
# @yieldparam [string] standard out response text
|
|
41
|
+
# @yieldparam [string] standard error response text
|
|
42
|
+
# @yieldreturn [WinRM::Output] The command output
|
|
43
|
+
def read_output(wsmv_message)
|
|
44
|
+
with_output do |output|
|
|
45
|
+
read_response(wsmv_message, true) do |stream, doc|
|
|
46
|
+
handled_out = handle_stream(stream, output, doc)
|
|
47
|
+
yield handled_out if handled_out && block_given?
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Reads streams sent in one or more receive response messages
|
|
53
|
+
# @param wsmv_message [WinRM::WSMV::Base] A wsmv message to send to endpoint
|
|
54
|
+
# @param wait_for_done_state whether to poll for a CommandState of Done
|
|
55
|
+
# @yieldparam [Hash] Hash representation of stream with type and text
|
|
56
|
+
# @yieldparam [REXML::Document] Complete SOAP envelope returned to wsmv_message
|
|
57
|
+
def read_response(wsmv_message, wait_for_done_state = false)
|
|
58
|
+
resp_doc = nil
|
|
59
|
+
until command_done?(resp_doc, wait_for_done_state)
|
|
60
|
+
logger.debug('[WinRM] Waiting for output...')
|
|
61
|
+
resp_doc = send_get_output_message(wsmv_message.build)
|
|
62
|
+
logger.debug('[WinRM] Processing output')
|
|
63
|
+
read_streams(resp_doc) do |stream|
|
|
64
|
+
yield stream, resp_doc
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
protected
|
|
70
|
+
|
|
71
|
+
def with_output
|
|
72
|
+
output = WinRM::Output.new
|
|
73
|
+
yield output
|
|
74
|
+
output.exitcode ||= 0
|
|
75
|
+
output
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def handle_stream(stream, output, resp_doc)
|
|
81
|
+
decoded_text = @output_decoder.decode(stream[:text])
|
|
82
|
+
return unless decoded_text
|
|
83
|
+
|
|
84
|
+
out = { stream[:type] => decoded_text }
|
|
85
|
+
output << out
|
|
86
|
+
if (code = REXML::XPath.first(resp_doc, "//*[local-name() = 'ExitCode']"))
|
|
87
|
+
output.exitcode = code.text.to_i
|
|
88
|
+
end
|
|
89
|
+
[out[:stdout], out[:stderr]]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def send_get_output_message(message)
|
|
93
|
+
@transport.send_request(message)
|
|
94
|
+
rescue WinRMWSManFault => e
|
|
95
|
+
# If no output is available before the wsman:OperationTimeout expires,
|
|
96
|
+
# the server MUST return a WSManFault with the Code attribute equal to
|
|
97
|
+
# 2150858793. When the client receives this fault, it SHOULD issue
|
|
98
|
+
# another Receive request.
|
|
99
|
+
# http://msdn.microsoft.com/en-us/library/cc251676.aspx
|
|
100
|
+
raise unless e.fault_code == '2150858793'
|
|
101
|
+
|
|
102
|
+
logger.debug('[WinRM] retrying receive request after timeout')
|
|
103
|
+
retry
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def command_done?(resp_doc, wait_for_done_state)
|
|
107
|
+
return false unless resp_doc
|
|
108
|
+
return true unless wait_for_done_state
|
|
109
|
+
|
|
110
|
+
REXML::XPath.match(
|
|
111
|
+
resp_doc,
|
|
112
|
+
"//*[@State='http://schemas.microsoft.com/wbem/wsman/1/windows/shell/" \
|
|
113
|
+
"CommandState/Done']"
|
|
114
|
+
).any?
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def read_streams(response_document)
|
|
118
|
+
body_path = "/*[local-name() = 'Envelope']/*[local-name() = 'Body']"
|
|
119
|
+
path = "#{body_path}/*[local-name() = 'ReceiveResponse']/*[local-name() = 'Stream']"
|
|
120
|
+
REXML::XPath.match(response_document, path).each do |stream|
|
|
121
|
+
next if stream.text.nil? || stream.text.empty?
|
|
122
|
+
|
|
123
|
+
yield type: stream.attributes['Name'].to_sym, text: stream.text
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
data/lib/winrm/wsmv/send_data.rb
CHANGED
data/lib/winrm/wsmv/soap.rb
CHANGED
data/lib/winrm/wsmv/wql_pull.rb
CHANGED
|
@@ -1,56 +1,54 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"#{NS_ENUM}:
|
|
49
|
-
"#{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
end
|
|
56
|
-
end
|
|
1
|
+
require 'nori'
|
|
2
|
+
require_relative 'base'
|
|
3
|
+
|
|
4
|
+
module WinRM
|
|
5
|
+
module WSMV
|
|
6
|
+
# WSMV message to 'pull' rest of enumeration results from Windows via WQL
|
|
7
|
+
class WqlPull < Base
|
|
8
|
+
def initialize(session_opts, namespace, enumeration_context)
|
|
9
|
+
@session_opts = session_opts
|
|
10
|
+
@namespace = namespace
|
|
11
|
+
@enumeration_context = enumeration_context
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def process_response(response)
|
|
15
|
+
parser = Nori.new(
|
|
16
|
+
parser: :rexml,
|
|
17
|
+
advanced_typecasting: false,
|
|
18
|
+
convert_tags_to: ->(tag) { tag.snakecase.to_sym },
|
|
19
|
+
strip_namespaces: true
|
|
20
|
+
)
|
|
21
|
+
parser.parse(response.to_s)[:envelope][:body]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
protected
|
|
25
|
+
|
|
26
|
+
def create_header(header)
|
|
27
|
+
header << Gyoku.xml(wql_header)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def create_body(body)
|
|
31
|
+
body.tag!("#{NS_ENUM}:Pull") { |en| en << Gyoku.xml(wql_body) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def wql_header
|
|
37
|
+
merge_headers(
|
|
38
|
+
shared_headers(@session_opts),
|
|
39
|
+
resource_uri_wmi(@namespace),
|
|
40
|
+
action_enumerate_pull
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def wql_body
|
|
45
|
+
{
|
|
46
|
+
"#{NS_ENUM}:EnumerationContext" => @enumeration_context,
|
|
47
|
+
"#{NS_WSMAN_DMTF}:OptimizeEnumeration" => nil,
|
|
48
|
+
"#{NS_ENUM}:MaxElements" => '32000',
|
|
49
|
+
"#{NS_WSMAN_MSFT}:SessionId" => "uuid:#{@session_opts[:session_id]}"
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/winrm/wsmv/wql_query.rb
CHANGED
|
@@ -1,99 +1,98 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@
|
|
26
|
-
@
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
"#{NS_WSMAN_DMTF}:
|
|
87
|
-
"#{NS_WSMAN_DMTF}:
|
|
88
|
-
"#{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
end
|
|
1
|
+
# Copyright 2016 Shawn Neal <sneal@sneal.net>
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
require 'nori'
|
|
16
|
+
require_relative 'base'
|
|
17
|
+
|
|
18
|
+
module WinRM
|
|
19
|
+
module WSMV
|
|
20
|
+
# WSMV message to query Windows via WQL
|
|
21
|
+
class WqlQuery < Base
|
|
22
|
+
def initialize(transport, session_opts, wql, namespace = nil)
|
|
23
|
+
@session_opts = session_opts
|
|
24
|
+
@wql = wql
|
|
25
|
+
@namespace = namespace
|
|
26
|
+
@transport = transport
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def process_response(response, &block)
|
|
30
|
+
parser = Nori.new(
|
|
31
|
+
parser: :rexml,
|
|
32
|
+
advanced_typecasting: false,
|
|
33
|
+
convert_tags_to: ->(tag) { tag.snakecase.to_sym },
|
|
34
|
+
strip_namespaces: true
|
|
35
|
+
)
|
|
36
|
+
@items = Hash.new { |h, k| h[k] = [] }
|
|
37
|
+
|
|
38
|
+
hresp = parser.parse(response.to_s)[:envelope][:body][:enumerate_response]
|
|
39
|
+
process_items hresp[:items], &block
|
|
40
|
+
|
|
41
|
+
# Perform WS-Enum PULL's until we have all the elements
|
|
42
|
+
enumeration_context = hresp[:enumeration_context]
|
|
43
|
+
until enumeration_context.nil?
|
|
44
|
+
query = WqlPull.new(@session_opts, @namespace, enumeration_context)
|
|
45
|
+
hresp = query.process_response(@transport.send_request(query.build))[:pull_response]
|
|
46
|
+
process_items hresp[:items], &block
|
|
47
|
+
enumeration_context = hresp[:enumeration_context]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
@items
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
protected
|
|
54
|
+
|
|
55
|
+
def create_header(header)
|
|
56
|
+
header << Gyoku.xml(wql_header)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def create_body(body)
|
|
60
|
+
body.tag!("#{NS_ENUM}:Enumerate") { |en| en << Gyoku.xml(wql_body) }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def process_items(items, &block)
|
|
66
|
+
return if items.nil?
|
|
67
|
+
|
|
68
|
+
items.each_pair do |k, v|
|
|
69
|
+
# Normalize items so the type always has an array even if it's just a single item.
|
|
70
|
+
v_ary = v.is_a?(Array) ? v : [v]
|
|
71
|
+
if block
|
|
72
|
+
v_ary.each { |val| yield k, val }
|
|
73
|
+
else
|
|
74
|
+
@items[k] += v_ary
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def wql_header
|
|
80
|
+
merge_headers(shared_headers(@session_opts), resource_uri_wmi(@namespace), action_enumerate)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def wql_body
|
|
84
|
+
{
|
|
85
|
+
"#{NS_WSMAN_DMTF}:OptimizeEnumeration" => nil,
|
|
86
|
+
"#{NS_WSMAN_DMTF}:MaxElements" => '32000',
|
|
87
|
+
"#{NS_WSMAN_DMTF}:Filter" => @wql,
|
|
88
|
+
"#{NS_WSMAN_MSFT}:SessionId" => "uuid:#{@session_opts[:session_id]}",
|
|
89
|
+
:attributes! => {
|
|
90
|
+
"#{NS_WSMAN_DMTF}:Filter" => {
|
|
91
|
+
'Dialect' => 'http://schemas.microsoft.com/wbem/wsman/1/WQL'
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
data/lib/winrm.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
#
|
|
3
1
|
# Copyright 2010 Dan Wanek <dan.wanek@gmail.com>
|
|
4
2
|
#
|
|
5
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -30,9 +28,9 @@ module WinRM
|
|
|
30
28
|
Logging.logger.root.appenders = Logging.appenders.stderr
|
|
31
29
|
rescue ArgumentError
|
|
32
30
|
# This means that the logging level wasn't valid
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
warn "Invalid WINRM_LOG level is set: #{ENV['WINRM_LOG']}"
|
|
32
|
+
warn ''
|
|
33
|
+
warn 'Please use one of the standard log levels: ' \
|
|
36
34
|
'debug, info, warn, or error'
|
|
37
35
|
end
|
|
38
36
|
end
|