winrm 0.0.1

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.
data/README ADDED
@@ -0,0 +1,53 @@
1
+ --------------------------------------------------------------------------
2
+ Windows Remote Management (WinRM) for Ruby
3
+ --------------------------------------------------------------------------
4
+ This is a SOAP library that uses the functionality in Windows Remote
5
+ Management(WinRM) to call native object in Windows. This includes, but is
6
+ not limitted to, running batch scripts, powershell scripts and fetching WMI
7
+ variables. For more information on WinRM, please visit Microsoft's WinRM
8
+ site: http://msdn.microsoft.com/en-us/library/aa384426(v=VS.85).aspx
9
+
10
+
11
+ My Info:
12
+ BLOG: http://distributed-frostbite.blogspot.com/
13
+ Add me in LinkedIn: http://www.linkedin.com/in/danwanek
14
+
15
+ --------------------------------------------------------------------------
16
+ --------------------------------------------------------------------------
17
+ TO USE:
18
+ require 'winrm'
19
+ # See REQUIRED GEMS below
20
+
21
+ gem install -r winrm
22
+
23
+ REQUIRED GEMS: (These should automatically install with the winrm gem)
24
+ # Handsoap
25
+ gem install -r handsoap
26
+ # Nokogiri XML Parser
27
+ gem install -r nokogiri
28
+ # HttpClient
29
+ gem install -r httpclient
30
+ # NTLM Library
31
+ gem install -r rubyntlm
32
+ #UUID Library
33
+ gem install -r uuid
34
+
35
+
36
+ EXAMPLE:
37
+ require 'winrm'
38
+ WinRM::WinRM.endpoint = 'http://mywinrmhost:5985/wsman'
39
+ WinRM::WinRM.set_auth('user','password')
40
+ winrm = WinRM::WinRM.instance
41
+ output = winrm.winrm.run_powershell_script 'script.ps1'
42
+ puts output[:stdout]
43
+
44
+ --------------------------------------------------------------------------
45
+ DISCLAIMER: If you see something that could be done better or would like
46
+ to help out in the development of this code please feel free to clone the
47
+ 'git' repository and send me patches:
48
+ git clone git://github.com/zenchild/WinRM.git
49
+ or add an issue on GitHub:
50
+ http://github.com/zenchild/WinRM/issues
51
+
52
+ Cheers!
53
+ --------------------------------------------------------------------------
data/Rakefile ADDED
@@ -0,0 +1,69 @@
1
+ require 'rubygems'
2
+ require 'rake/clean'
3
+ require 'rake/gempackagetask'
4
+ require 'date'
5
+
6
+ CLEAN.include("pkg")
7
+ CLEAN.include("doc")
8
+
9
+ GEMSPEC = Gem::Specification.new do |gem|
10
+ gem.name = "winrm"
11
+ gem.version = File.open('VERSION').readline.chomp
12
+ gem.date = Date.today.to_s
13
+ gem.platform = Gem::Platform::RUBY
14
+ gem.rubyforge_project = nil
15
+
16
+ gem.author = "Dan Wanek"
17
+ gem.email = "dan.wanek@gmail.com"
18
+ gem.homepage = "http://github.com/zenchild/WinRM"
19
+
20
+ gem.summary = 'Ruby library for Windows Remote Management'
21
+ gem.description = <<-EOF
22
+ Ruby library for Windows Remote Management
23
+ EOF
24
+
25
+ gem.files = `git ls-files`.split(/\n/)
26
+ gem.require_path = "lib"
27
+ gem.rdoc_options = %w(-x test/ -x examples/)
28
+ gem.extra_rdoc_files = %w(README COPYING.txt)
29
+
30
+ gem.required_ruby_version = '>= 1.8.7'
31
+ gem.add_runtime_dependency 'handsoap'
32
+ gem.add_runtime_dependency 'nokogiri'
33
+ gem.add_runtime_dependency 'httpclient'
34
+ gem.add_runtime_dependency 'rubyntlm'
35
+ gem.add_runtime_dependency 'uuid'
36
+ end
37
+
38
+ Rake::GemPackageTask.new(GEMSPEC) do |pkg|
39
+ pkg.need_tar = true
40
+ end
41
+
42
+ task :default => [:buildgem]
43
+
44
+ desc "Build the gem without a version change"
45
+ task :buildgem => [:clean, :repackage]
46
+
47
+ desc "Build the gem, but increment the version first"
48
+ task :newrelease => [:versionup, :clean, :repackage]
49
+
50
+
51
+ desc "Increment the version by 1 minor release"
52
+ task :versionup do
53
+ ver = up_min_version
54
+ puts "New version: #{ver}"
55
+ end
56
+
57
+
58
+ def up_min_version
59
+ f = File.open('VERSION', 'r+')
60
+ ver = f.readline.chomp
61
+ v_arr = ver.split(/\./).map do |v|
62
+ v.to_i
63
+ end
64
+ v_arr[2] += 1
65
+ ver = v_arr.join('.')
66
+ f.rewind
67
+ f.write(ver)
68
+ ver
69
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,37 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
3
+ #
4
+ #
5
+ # This file is part of WinRM.
6
+ #
7
+ # WinRM is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # WinRM is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with WinRM. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+
21
+ # Custom extensions to the class String
22
+ class String
23
+ # Change CamelCased strings to ruby_cased strings
24
+ # It uses the lookahead assertion ?= In this case it basically says match
25
+ # anything followed by a capital letter, but not the capital letter itself.
26
+ # @see http://www.pcre.org/pcre.txt The PCRE guide for more details
27
+ def ruby_case
28
+ self.split(/(?=[A-Z])/).join('_').downcase
29
+ end
30
+
31
+ # Change a ruby_cased string to CamelCased
32
+ def camel_case
33
+ self.split(/_/).map { |i|
34
+ i.sub(/^./) { |s| s.upcase }
35
+ }.join
36
+ end
37
+ end # String
@@ -0,0 +1,28 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
3
+ #
4
+ #
5
+ # This file is part of WinRM.
6
+ #
7
+ # WinRM is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # WinRM is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with WinRM. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+
21
+ module WinRM
22
+ module SOAP
23
+ # Generic WinRM SOAP Error
24
+ class WinRMWebServiceError < StandardError
25
+ end
26
+ end # SOAP
27
+ end # WinRM
28
+
@@ -0,0 +1,36 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
3
+ #
4
+ #
5
+ # This file is part of WinRM.
6
+ #
7
+ # WinRM is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # WinRM is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with WinRM. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+ require 'handsoap'
21
+
22
+ module WinRM
23
+ module SOAP
24
+ NS_ADDRESSING ='a' # http://schemas.xmlsoap.org/ws/2004/08/addressing
25
+ NS_CIMBINDING ='b' # http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd
26
+ NS_ENUM ='n' # http://schemas.xmlsoap.org/ws/2004/09/enumeration
27
+ NS_TRANSFER ='x' # http://schemas.xmlsoap.org/ws/2004/09/transfer
28
+ NS_WSMAN_DMTF ='w' # http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
29
+ NS_WSMAN_MSFT ='p' # http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd
30
+ NS_SCHEMA_INST ='xsi' # http://www.w3.org/2001/XMLSchema-instance
31
+ NS_WIN_SHELL ='rsp' # http://schemas.microsoft.com/wbem/wsman/1/windows/shell
32
+ end
33
+ end
34
+
35
+ require 'soap/exceptions/exceptions'
36
+ require 'soap/winrm_service'
@@ -0,0 +1,345 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
3
+ #
4
+ #
5
+ # This file is part of WinRM.
6
+ #
7
+ # WinRM is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # WinRM is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with WinRM. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+ Handsoap.http_driver = :http_client
21
+
22
+ module WinRM
23
+ module SOAP
24
+ class WinRMWebService < Handsoap::Service
25
+ include SOAP
26
+
27
+ @@raw_soap = false
28
+
29
+ def initialize()
30
+ if $DEBUG
31
+ @debug = File.new('winrm_debug.out', 'w')
32
+ @debug.sync = true
33
+ end
34
+
35
+ end
36
+
37
+ def self.set_auth(user,pass)
38
+ @@user = user
39
+ @@pass = pass
40
+ end
41
+
42
+ # Turn off parsing and just return the soap response
43
+ def self.raw_soap!
44
+ @@raw_soap = true
45
+ end
46
+
47
+
48
+ # ********* Begin Hooks *********
49
+
50
+ def on_create_document(doc)
51
+ doc.alias NS_ADDRESSING, 'http://schemas.xmlsoap.org/ws/2004/08/addressing'
52
+ doc.alias NS_ENUM, 'http://schemas.xmlsoap.org/ws/2004/09/enumeration'
53
+ doc.alias NS_WSMAN_DMTF, 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd'
54
+ doc.alias NS_WSMAN_MSFT, 'http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd'
55
+ doc.alias NS_SCHEMA_INST,'http://www.w3.org/2001/XMLSchema-instance'
56
+ doc.alias NS_WIN_SHELL, 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell'
57
+ doc.alias NS_CIMBINDING, 'http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd'
58
+
59
+ header = doc.find('Header')
60
+ header.add("#{NS_ADDRESSING}:To", WinRMWebService.uri)
61
+ header.add("#{NS_ADDRESSING}:ReplyTo") {|rto|
62
+ rto.add("#{NS_ADDRESSING}:Address",'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous') {|addr|
63
+ addr.set_attr('mustUnderstand','true')
64
+ }
65
+ }
66
+ header.add("#{NS_WSMAN_DMTF}:MaxEnvelopeSize",'153600') {|mes|
67
+ mes.set_attr('mustUnderstand','true')
68
+ }
69
+ header.add("#{NS_ADDRESSING}:MessageID", "uuid:#{UUID.generate.upcase}")
70
+ header.add("#{NS_WSMAN_DMTF}:Locale") {|loc|
71
+ loc.set_attr('xml:lang','en-US')
72
+ loc.set_attr('mustUnderstand','false')
73
+ }
74
+ header.add("#{NS_WSMAN_MSFT}:DataLocale") {|loc|
75
+ loc.set_attr('xml:lang','en-US')
76
+ loc.set_attr('mustUnderstand','false')
77
+ }
78
+ header.add("#{NS_WSMAN_DMTF}:OperationTimeout",'PT60.000S')
79
+ end
80
+
81
+ # Adds knowledge of namespaces to the response object. These have to be identical to the
82
+ # URIs returned in the XML response. For example, I had some issues with the 'soap'
83
+ # namespace because my original URI did not end in a '/'
84
+ # @example
85
+ # Won't work: http://schemas.xmlsoap.org/soap/envelope
86
+ # Works: http://schemas.xmlsoap.org/soap/envelope/
87
+ def on_response_document(doc)
88
+ doc.add_namespace NS_ADDRESSING, 'http://schemas.xmlsoap.org/ws/2004/08/addressing'
89
+ doc.add_namespace NS_ENUM, 'http://schemas.xmlsoap.org/ws/2004/09/enumeration'
90
+ doc.add_namespace NS_TRANSFER, 'http://schemas.xmlsoap.org/ws/2004/09/transfer'
91
+ doc.add_namespace NS_WSMAN_DMTF, 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd'
92
+ doc.add_namespace NS_WSMAN_MSFT, 'http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd'
93
+ doc.add_namespace NS_WIN_SHELL, 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell'
94
+ doc.add_namespace NS_CIMBINDING, 'http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd'
95
+ end
96
+
97
+ def on_after_create_http_request(req)
98
+ req.set_auth @@user, @@pass
99
+ req.set_header('Content-Type','application/soap+xml;charset=UTF-8')
100
+ #puts "SOAP DOCUMENT=\n#{req.body}"
101
+ end
102
+
103
+ def on_http_error(resp)
104
+ puts "HTTP ERROR: #{resp.status}"
105
+ puts "HEADERS=\n#{resp.headers}"
106
+ puts "BODY=\n#{resp.body}"
107
+ end
108
+
109
+
110
+ # ********** End Hooks **********
111
+
112
+
113
+ # Create a Shell on the destination host
114
+ # @param [String<optional>] i_stream Which input stream to open. Leave this alone unless you know what you're doing
115
+ # @param [String<optional>] o_stream Which output stream to open. Leave this alone unless you know what you're doing
116
+ # @return [String] The ShellId from the SOAP response. This is our open shell instance on the remote machine.
117
+ def open_shell(i_stream = 'stdin', o_stream = 'stdout stderr')
118
+ header = {
119
+ "#{NS_WSMAN_DMTF}:OptionSet" => [
120
+ {"#{NS_WSMAN_DMTF}:Option" => {:name => 'WINRS_NOPROFILE', :text =>"FALSE"}},
121
+ {"#{NS_WSMAN_DMTF}:Option" => {:name => 'WINRS_CODEPAGE', :text =>"437"}}
122
+ ]
123
+ }.merge(resource_uri_cmd).merge(action_create)
124
+
125
+ resp = invoke("#{NS_WIN_SHELL}:Shell", {:soap_action => :auto, :http_options => nil, :soap_header => header}) do |shell|
126
+ shell.add("#{NS_WIN_SHELL}:InputStreams", i_stream)
127
+ shell.add("#{NS_WIN_SHELL}:OutputStreams",o_stream)
128
+ end
129
+
130
+ # Get the Shell ID from the response
131
+ (resp/"//*[@Name='ShellId']").to_s
132
+ end
133
+
134
+ # Run a command on a machine with an open shell
135
+ # @param [String] shell_id The shell id on the remote machine. See #open_shell
136
+ # @param [String] command The command to run on the remote machine
137
+ # @return [String] The CommandId from the SOAP response. This is the ID we need to query in order to get output.
138
+ def run_command(shell_id, command)
139
+ header = {
140
+ "#{NS_WSMAN_DMTF}:OptionSet" => {
141
+ "#{NS_WSMAN_DMTF}:Option" => {:name => 'WINRS_CONSOLEMODE_STDIN', :text =>"TRUE"},
142
+ }
143
+ }.merge(resource_uri_cmd).merge(action_command).merge(selector_shell_id(shell_id))
144
+
145
+ # Issue the Command
146
+ resp = invoke("#{NS_WIN_SHELL}:CommandLine", {:soap_action => :auto, :http_options => nil, :soap_header => header}) do |cli|
147
+ cli.add("#{NS_WIN_SHELL}:Command","\"#{command}\"")
148
+ end
149
+
150
+ (resp/"//#{NS_WIN_SHELL}:CommandId").to_s
151
+ end
152
+
153
+ # Get the Output of the given shell and command
154
+ # @param [String] shell_id The shell id on the remote machine. See #open_shell
155
+ # @param [String] command_id The command id on the remote machine. See #run_command
156
+ # @return [Hash] :stdout and :stderr
157
+ def get_command_output(shell_id, command_id)
158
+ header = {}.merge(resource_uri_cmd).merge(action_receive).merge(selector_shell_id(shell_id))
159
+
160
+ # Get Command Output
161
+ resp = invoke("#{NS_WIN_SHELL}:Receive", {:soap_action => :auto, :http_options => nil, :soap_header => header}) do |rec|
162
+ rec.add("#{NS_WIN_SHELL}:DesiredStream",'stdout stderr') do |ds|
163
+ ds.set_attr('CommandId', command_id)
164
+ end
165
+ end
166
+
167
+ cmd_stdout = ''
168
+ cmd_stderr = ''
169
+ (resp/"//*[@Name='stdout']").each do |n|
170
+ next if n.to_s.nil?
171
+ cmd_stdout << Base64.decode64(n.to_s)
172
+ end
173
+ (resp/"//*[@Name='stderr']").each do |n|
174
+ next if n.to_s.nil?
175
+ cmd_stderr << Base64.decode64(n.to_s)
176
+ end
177
+ {:stdout => cmd_stdout, :stderr => cmd_stderr}
178
+ end
179
+
180
+ # Clean-up after a command.
181
+ # @see #run_command
182
+ # @param [String] shell_id The shell id on the remote machine. See #open_shell
183
+ # @param [String] command_id The command id on the remote machine. See #run_command
184
+ # @return [true] This should have more error checking but it just returns true for now.
185
+ def cleanup_command(shell_id, command_id)
186
+ header = {}.merge(resource_uri_cmd).merge(action_signal).merge(selector_shell_id(shell_id))
187
+ # Signal the Command references to terminate (close stdout/stderr)
188
+ resp = invoke("#{NS_WIN_SHELL}:Signal", {:soap_action => :auto, :http_options => nil, :soap_header => header}) do |sig|
189
+ sig.set_attr('CommandId', command_id)
190
+ sig.add("#{NS_WIN_SHELL}:Code",'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/signal/terminate')
191
+ end
192
+ true
193
+ end
194
+
195
+ # Close the shell
196
+ # @param [String] shell_id The shell id on the remote machine. See #open_shell
197
+ # @return [true] This should have more error checking but it just returns true for now.
198
+ def close_shell(shell_id)
199
+ header = {}.merge(resource_uri_cmd).merge(action_delete).merge(selector_shell_id(shell_id))
200
+ # Delete the Shell reference
201
+ resp = invoke(:nil_body, {:soap_action => nil, :soap_body => true, :http_options => nil, :soap_header => header})
202
+ true
203
+ end
204
+
205
+ # Run a Powershell script that resides on the local box.
206
+ # @param [String] script_file The string representing the path to a Powershell script
207
+ # @return [Hash] :stdout and :stderr
208
+ def run_powershell_script(script_file)
209
+ script = File.read(script_file)
210
+ script = script.chars.to_a.join("\x00").chomp.encode('ASCII-8BIT')
211
+ script = Base64.strict_encode64(script)
212
+
213
+ shell_id = open_shell
214
+ command_id = run_command(shell_id, "powershell -encodedCommand #{script}")
215
+ command_output = get_command_output(shell_id, command_id)
216
+ cleanup_command(shell_id, command_id)
217
+ close_shell(shell_id)
218
+ command_output
219
+ end
220
+
221
+
222
+ # Run a WQL Query
223
+ # @see http://msdn.microsoft.com/en-us/library/aa394606(VS.85).aspx
224
+ # @param [String] wql The WQL query
225
+ # @return [Array<Hash>] Returns an array of Hashes that contain the key/value pairs returned from the query.
226
+ def run_wql(wql)
227
+ header = {}.merge(resource_uri_wmi).merge(action_enumerate)
228
+
229
+ begin
230
+ resp = invoke("#{NS_ENUM}:Enumerate", {:soap_action => :auto, :http_options => nil, :soap_header => header}) do |enum|
231
+ enum.add("#{NS_WSMAN_DMTF}:OptimizeEnumeration")
232
+ enum.add("#{NS_WSMAN_DMTF}:MaxElements",'32000')
233
+ mattr = nil
234
+ enum.add("#{NS_WSMAN_DMTF}:Filter", wql) do |filt|
235
+ filt.set_attr('Dialect','http://schemas.microsoft.com/wbem/wsman/1/WQL')
236
+ end
237
+ end
238
+ rescue Handsoap::Fault => e
239
+ raise WinRMWebServiceError, e.reason
240
+ end
241
+
242
+ query_response = []
243
+ (resp/"//#{NS_ENUM}:EnumerateResponse//#{NS_WSMAN_DMTF}:Items/*").each do |i|
244
+ qitem = {}
245
+ (i/'*').each do |si|
246
+ qitem[si.node_name] = si.to_s
247
+ end
248
+ query_response << qitem
249
+ end
250
+ query_response
251
+ end
252
+
253
+
254
+ # To create an empty body set :soap_body => true in the invoke options and set the action to :nil_body
255
+ def iterate_hash_array(element, hash_array)
256
+ add_hierarchy!(element, hash_array, nil) unless hash_array.key?(:nil_body)
257
+ end
258
+
259
+
260
+ protected
261
+
262
+ # Add a hierarchy of elements from hash data
263
+ # @example Hash to XML
264
+ # {:this => {:text =>'that'},'top' => {:id => '32fss', :text => 'TestText', {'middle' => 'bottom'}}}
265
+ # becomes...
266
+ # <this>that</this>
267
+ # <top Id='32fss'>
268
+ # TestText
269
+ # <middle>bottom</middle>
270
+ # </top>
271
+ def add_hierarchy!(node, e_hash, prefix = NS_ADDRESSING)
272
+ prefix << ":" unless prefix.nil?
273
+ e_hash.each_pair do |k,v|
274
+ name = (k.is_a?(Symbol) && k != :text) ? k.to_s.camel_case : k
275
+ if v.is_a? Hash
276
+ node.add("#{prefix}#{name}", v[:text]) do |n|
277
+ add_hierarchy!(n, v, prefix)
278
+ end
279
+ elsif v.is_a? Array
280
+ node.add("#{prefix}#{name}") do |n|
281
+ v.each do |i|
282
+ add_hierarchy!(n, i, prefix)
283
+ end
284
+ end
285
+ else
286
+ node.set_attr(name, v) unless k == :text
287
+ end
288
+ end
289
+ end
290
+
291
+
292
+ # Private Methods (Builders and Parsers)
293
+ private
294
+
295
+ def build!(node, opts = {}, &block)
296
+ #EwsBuilder.new(node, opts, &block)
297
+ end
298
+
299
+ def parse!(response, opts = {})
300
+ return response if @@raw_soap
301
+ #EwsParser.new(response).parse(opts)
302
+ end
303
+
304
+
305
+ # Helper methods for SOAP Headers
306
+
307
+ def resource_uri_cmd
308
+ {"#{NS_WSMAN_DMTF}:ResourceURI" => {'mustUnderstand' => 'true', :text => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd'}}
309
+ end
310
+
311
+ def resource_uri_wmi(namespace = 'root/cimv2/*')
312
+ {"#{NS_WSMAN_DMTF}:ResourceURI" => {'mustUnderstand' => 'true', :text => "http://schemas.microsoft.com/wbem/wsman/1/wmi/#{namespace}"}}
313
+ end
314
+
315
+ def action_create
316
+ {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => 'true', :text => 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Create'}}
317
+ end
318
+
319
+ def action_delete
320
+ {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => 'true', :text => 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete'}}
321
+ end
322
+
323
+ def action_command
324
+ {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => 'true', :text => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Command'}}
325
+ end
326
+
327
+ def action_receive
328
+ {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => 'true', :text => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive'}}
329
+ end
330
+
331
+ def action_signal
332
+ {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => 'true', :text => 'http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Signal'}}
333
+ end
334
+
335
+ def action_enumerate
336
+ {"#{NS_ADDRESSING}:Action" => {'mustUnderstand' => 'true', :text => 'http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate'}}
337
+ end
338
+
339
+ def selector_shell_id(shell_id)
340
+ {"#{NS_WSMAN_DMTF}:SelectorSet" => {"#{NS_WSMAN_DMTF}:Selector" => {:name => 'ShellId', :text => shell_id}}}
341
+ end
342
+
343
+ end # class WinRMWebService
344
+ end # module SOAP
345
+ end # WinRM
data/lib/winrm.rb ADDED
@@ -0,0 +1,89 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
3
+ #
4
+ #
5
+ # This file is part of WinRM.
6
+ #
7
+ # WinRM is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # WinRM is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with WinRM. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+
21
+ # We only what one instance of this class so include Singleton
22
+ require 'singleton'
23
+ require 'date'
24
+ require 'base64'
25
+ require 'uuid'
26
+ require 'kconv'
27
+
28
+ # Class Extensions
29
+ require 'extensions/string'
30
+
31
+ # Load the backend SOAP infrastructure. Today this is Handsoap.
32
+ require 'soap/soap_provider'
33
+
34
+
35
+ module WinRM
36
+ class WinRM
37
+ include Singleton
38
+
39
+ attr_reader :winrm
40
+
41
+ # Set the endpoint for WinRM Web Services.
42
+ # @param [String] endpoint The URL of the endpoint.
43
+ # https://myserver:5986/wsman
44
+ # @param [Integer] version The SOAP version to use. This defaults to 1
45
+ # and you should not need to pass this parameter.
46
+ def self.endpoint=(endpoint, version = 2)
47
+ @@endpoint = endpoint
48
+ SOAP::WinRMWebService.endpoint(:uri => endpoint, :version => version)
49
+ end
50
+
51
+ # Fetch the current endpoint
52
+ def self.endpoint
53
+ @@endpoint
54
+ end
55
+
56
+ # Set the SOAP username and password.
57
+ # @param [String] user The user name
58
+ # @param [String] pass The password
59
+ def self.set_auth(user,pass)
60
+ @@user = user
61
+ SOAP::WinRMWebService.set_auth(user,pass)
62
+ end
63
+
64
+ # Set the http driver that the SOAP back-end will use.
65
+ # @param [Symbol] driver The HTTP driver. Available drivers:
66
+ # :curb, :net_http, :http_client(Default)
67
+ def self.set_http_driver(driver)
68
+ Handsoap.http_driver = driver
69
+ end
70
+
71
+ def initialize
72
+ @winrm = SOAP::WinRMWebService.new
73
+ end
74
+
75
+ # Run a Powershell script
76
+ # @see WinRM::SOAP::WinRMWebService#run_powershell_script
77
+ def powershell(script_file)
78
+ @winrm.run_powershell_script(script_file)
79
+ end
80
+
81
+ # Run a WQL Query
82
+ # @see WinRM::SOAP::WinRMWebService#run_wql
83
+ # @see http://msdn.microsoft.com/en-us/library/aa394606(VS.85).aspx
84
+ def wql(wql)
85
+ @winrm.run_wql(wql)
86
+ end
87
+
88
+ end # class WinRM
89
+ end
data/preamble ADDED
@@ -0,0 +1,19 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
3
+ #
4
+ #
5
+ # This file is part of WinRM.
6
+ #
7
+ # WinRM is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # WinRM is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with WinRM. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################