Class: Channelizer::Channels::WinRM

Inherits:
Base
  • Object
show all
Defined in:
lib/channelizer/channels/winrm.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#ready?, required_option, #shell_execute, validate_options

Methods included from Util::Retryable

#retryable

Constructor Details

#initialize(options) ⇒ WinRM

Creates a WinRM Channel

Parameters:

  • options (Hash)

    a customizable set of options

Options Hash (options):

  • :username (String)

    the username

  • :password (String)

    the password

  • :host (String)

    the remote host

  • :port (String) — default: 5985

    the port to connect on

  • :realm (String)

    the realm to use when using kerberos authentication



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/channelizer/channels/winrm.rb', line 20

def initialize(options)
  defaults = { :port => 5985, :basic_auth_only => true }
  options = defaults.merge(options)
  options[:pass] = options[:password] if options[:password]
  options[:user] = options[:username] if options[:username]

  # Options need to be in a final state before we call the parent initializer
  super(options)

  endpoint = "http://#{options[:host]}:#{options[:port]}/wsman"

  if options[:realm]
    @session = ::WinRM::WinRMWebService.new(endpoint, :kerberos, :realm => options[:realm])
  else
    @session = ::WinRM::WinRMWebService.new(endpoint, :plaintext, options)
  end

end

Instance Attribute Details

#sessionWinRM::WinRMWebService (readonly)

Returns the winrm management session.

Returns:

  • (WinRM::WinRMWebService)

    the winrm management session



7
8
9
# File 'lib/channelizer/channels/winrm.rb', line 7

def session
  @session
end

Instance Method Details

#execute(command, options = { }) ⇒ Fixnum

Executes a command on the channel

Parameters:

  • command

    the command to execute on the channel

Returns:

  • (Fixnum)

    the exit code of the command

Raises:

  • (StandardException)


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
# File 'lib/channelizer/channels/winrm.rb', line 44

def execute(command, options = { })
  defaults = { :shell => :cmd, :out_console => true }
  options = defaults.merge(options)

  run_proc = Proc.new do |stdout, stderr|
    STDOUT.print stdout
    STDERR.print stderr
  end

  shell = options.delete(:shell)
  case shell
  when :cmd
    if options[:out_console]
      status = session.cmd(command,&run_proc) 
    else
      status = session.cmd(command)
    end
  when :powershell
    if options[:out_console]
      status = session.powershell(command, &run_proc)
    else
      status = session.powershell(command)
    end  
  else
    raise StandardError, "Invalid shell #{options[:shell]}"
  end
  status[:exitcode]
end

#sudo_command(command) ⇒ String

Echos the command (Windows does not support sudo)

Parameters:

  • command (String)

    the command to wrap in a sudo context

Returns:

  • (String)

    the command that has been wrapped in a sudo context



77
78
79
# File 'lib/channelizer/channels/winrm.rb', line 77

def sudo_command(command)
  command
end

#upload(source, destination, options = {}) ⇒ Fixnum

Uploads a file over WinRM

Parameters:

  • source

    the file to upload

  • destination

    where to place the file on the remote host

Returns:

  • (Fixnum)


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
# File 'lib/channelizer/channels/winrm.rb', line 86

def upload(source, destination, options = {} )
  file = "winrm-upload-#{rand()}"
  puts "File: " + file
  file_name = (session.cmd("echo %TEMP%\\#{file}"))[:data][0][:stdout].chomp
  puts "File Name: " + file_name
  puts session.powershell <<-EOH
    if(Test-Path #{destination})
    {
      rm #{destination}
    }
  EOH

  Base64.encode64(IO.binread(source)).gsub("\n",'').chars.to_a.each_slice(8000-file_name.size) do |chunk|
    out = session.cmd( "echo #{chunk.join} >> \"#{file_name}\"" )
    puts out
  end

  puts session.powershell <<-EOH
    $dir = [System.IO.Path]::GetDirectoryName(\"#{destination}\")
    Write-host $dir
    New-Item $dir -type directory -ea SilentlyContinue
  EOH

  puts session.powershell <<-EOH
    $base64_string = Get-Content \"#{file_name}\"
    $bytes  = [System.Convert]::FromBase64String($base64_string) 
    $new_file = [System.IO.Path]::GetFullPath(\"#{destination}\")
    [System.IO.File]::WriteAllBytes($new_file,$bytes)
  EOH
end