Class: Ievms::WindowsGuest

Inherits:
Object
  • Object
show all
Defined in:
lib/ievms/windows_guest.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(vbox_name) ⇒ WindowsGuest

Returns a new instance of WindowsGuest.



22
23
24
25
26
27
28
29
30
31
# File 'lib/ievms/windows_guest.rb', line 22

def initialize(vbox_name)
  @vbox_name = vbox_name

  check_virtualbox_version
  is_vm?

  @verbose = false
  @headless = true
  @timeout_secs = 600 #default timeout for a single task 5 minutes
end

Instance Attribute Details

#headlessObject

Returns the value of attribute headless.



19
20
21
# File 'lib/ievms/windows_guest.rb', line 19

def headless
  @headless
end

#timeout_secsObject

Returns the value of attribute timeout_secs.



20
21
22
# File 'lib/ievms/windows_guest.rb', line 20

def timeout_secs
  @timeout_secs
end

#verboseObject

Returns the value of attribute verbose.



18
19
20
# File 'lib/ievms/windows_guest.rb', line 18

def verbose
  @verbose
end

Instance Method Details

#boot_complete?Boolean

return true when run level is 3 boot complete

Returns:

  • (Boolean)


255
256
257
258
259
260
261
# File 'lib/ievms/windows_guest.rb', line 255

def boot_complete?
  out = `VBoxManage showvminfo "#{@vbox_name}" | grep 'Additions run level:'`
  print out if @verbose
  if out[-2..-2].to_i == 3
    return true
  end
end

#choco_install(pkg, quiet = false) ⇒ Object

install choco package(s)



201
202
203
204
205
206
207
208
209
# File 'lib/ievms/windows_guest.rb', line 201

def choco_install(pkg, quiet=false)
  if ! chocolatey?
    log_stdout "First time.. installing Chocolatey first", quiet
    install_chocolatey
  end

  log_stdout "Installing with choco: #{pkg} \n", quiet
  run_powershell_cmd_as_admin("choco install -y #{pkg}", false)
end

#choco_uninstall(pkg, quiet = false) ⇒ Object

uninstall package(s)



212
213
214
215
216
217
218
219
# File 'lib/ievms/windows_guest.rb', line 212

def choco_uninstall(pkg,quiet=false)
  if chocolatey?
    log_stdout "Uninstalling with choco: #{pkg} \n", false
    run_powershell_cmd_as_admin("cuninst -y #{pkg}", false)
  else
    log_stdout "Chocolatey is not installed, guess you don't need to uninstall anything.", quiet
  end
end

#chocolatey?Boolean

is chocolatey installed

Returns:

  • (Boolean)


222
223
224
225
226
227
228
229
# File 'lib/ievms/windows_guest.rb', line 222

def chocolatey?
  out = run_command_as_admin('@powershell -Command "choco"',false)
  if out.include?("CommandNotFoundException")
    return false
  else
    return true
  end
end

#download_file_from_guest(guest_path, local_path, quiet = false) ⇒ Object

copy file from guest (win) machine to host machine



34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ievms/windows_guest.rb', line 34

def download_file_from_guest(guest_path, local_path, quiet=false)

  log_stdout "Copying #{guest_path} to #{local_path}", quiet
  # 1 run cp command in machine
  guestcontrol_exec "cmd.exe", "cmd.exe /c copy \"#{guest_path}\" \"E:\\#{File.basename(local_path)}\""

  # 2 copy to tmp location in .ievms
  FileUtils.cp File.join(IEVMS_HOME,File.basename(local_path)), local_path

  # 3 remove tmp file in .ievms
  FileUtils.rm File.join(IEVMS_HOME,File.basename(local_path))
end

#download_string_from_file_to_guest(guest_path, quiet = false) ⇒ Object

return string from remote file



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/ievms/windows_guest.rb', line 62

def download_string_from_file_to_guest( guest_path, quiet=false)
  log_stdout "Copying #{guest_path} to tempfile.txt", quiet
  guestcontrol_exec "cmd.exe", "cmd.exe /c copy \"#{guest_path}\" \"E:\\tmpfile.txt\""

  tmpfile = File.join(IEVMS_HOME,'tmpfile.txt')
  if File.exists? tmpfile
    string = IO.read(tmpfile)
    FileUtils.rm tmpfile
  else
    string = ''
  end
  string
end

#end_ievms_task(quiet = true) ⇒ Object

end the administrative task



239
240
241
# File 'lib/ievms/windows_guest.rb', line 239

def end_ievms_task(quiet=true)
  run_command('schtasks.exe /End /TN ievms', quiet)
end

#install_chocolatey(quiet = false) ⇒ Object

install the Chocolatey Package Manager for Windows



232
233
234
235
236
# File 'lib/ievms/windows_guest.rb', line 232

def install_chocolatey(quiet=false)
  log_stdout "Installing Chocolatey", quiet
  run_command_as_admin('@powershell -NoProfile -ExecutionPolicy unrestricted -Command "(iex ((new-object net.webclient).DownloadString(\'https://chocolatey.org/install.ps1\'))) >$null 2>&1" && SET PATH=%PATH%;%ALLUSERSPROFILE%\cchocolatey\bin')
  reboot
end

#powered_off?Boolean

true when machine powered off

Returns:

  • (Boolean)


244
245
246
247
248
249
250
251
252
# File 'lib/ievms/windows_guest.rb', line 244

def powered_off?
  cmd = "VBoxManage showvminfo \"#{@vbox_name}\" | grep \"State:\""
  print cmd if @verbose
  out = `#{cmd}`
  print out if @verbose
  if out.include?('powered off') || out.include?('aborted')
    return true
  end
end

#reboot(quiet = false) ⇒ Object

reboot windows machine



179
180
181
182
183
# File 'lib/ievms/windows_guest.rb', line 179

def reboot(quiet=false)
  log_stdout "rebooting...", quiet
  shutdown(true)
  start(true)
end

#restore_clean_snapshot(quiet = false) ⇒ Object



185
186
187
188
189
190
191
192
# File 'lib/ievms/windows_guest.rb', line 185

def restore_clean_snapshot(quiet=false)
  log_stdout "Restoring Clean Snapshot ...", quiet
  shutdown
  cmd = "VBoxManage snapshot \"#{@vbox_name}\" restore clean"
  log_stdout cmd, false if @verbose
  stdout,_,_ = Open3.capture3(cmd)
  print stdout
end

#run_command(command, quiet = false) ⇒ Object

execute existing batch file in Windows guest



133
134
135
136
137
# File 'lib/ievms/windows_guest.rb', line 133

def run_command(command, quiet=false)
  log_stdout "Executing command: #{command}", quiet
  out, _, _ = guestcontrol_exec "cmd.exe", "cmd.exe /c \"#{command}\""
  out
end

#run_command_as_admin(command, quiet = false, dont_wait = false) ⇒ Object

execute existing batch file in Windows guest as Administrator



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
127
128
129
130
# File 'lib/ievms/windows_guest.rb', line 99

def run_command_as_admin(command,quiet=false, dont_wait=false)
  log_stdout "Executing command as administrator: #{command}", quiet

  run_command 'if exist C:\Users\IEUser\ievms.bat del C:\Users\IEUser\ievms.bat && Exit', true
  upload_string_as_file_to_guest('C:\Users\IEUser\ievms_cmd.bat > C:\Users\IEUser\ievms.txt', 'C:\Users\IEUser\ievms.bat', true)

  run_command 'if exist C:\Users\IEUser\ievms.bat del C:\Users\IEUser\ievms_cmd.bat && Exit', true
  upload_string_as_file_to_guest(command, 'C:\Users\IEUser\ievms_cmd.bat', true)

  if(dont_wait)
    guestcontrol_exec "schtasks.exe", "schtasks.exe /run /tn ievms"
    return
  end

  _ = Timeout::timeout(@timeout_secs) {

    guestcontrol_exec "schtasks.exe", "schtasks.exe /run /tn ievms"

    unless quiet
      print "..."
      while schtasks_query_ievms.include? 'Running'
        print "."
        sleep 1
      end
      print "\n"
    end
  }

  run_command 'if exist C:\Users\IEUser\ievms.bat del C:\Users\IEUser\ievms_cmd.bat && Exit', true
  print download_string_from_file_to_guest 'c:\Users\IEUser\ievms.txt' unless quiet
  download_string_from_file_to_guest 'c:\Users\IEUser\ievms.txt', true
end

#run_powershell_cmd_as_admin(command, quiet = false) ⇒ Object

def run_powershell_cmd(command, quiet=false)

run_command '@powershell -NoProfile -Command "' + command +'"', quiet

end



144
145
146
# File 'lib/ievms/windows_guest.rb', line 144

def run_powershell_cmd_as_admin(command, quiet=false)
  run_command_as_admin  '@powershell -NoProfile -ExecutionPolicy unrestricted -Command "' + command + '"', quiet
end

#schtasks_query_ievmsObject

show status of administrative ievms task.



195
196
197
198
# File 'lib/ievms/windows_guest.rb', line 195

def schtasks_query_ievms
  out, _, _ = guestcontrol_exec "schtasks.exe", "schtasks.exe /query /tn ievms"
  out
end

#shutdown(quiet = false) ⇒ Object

shutdown windows machine



149
150
151
152
153
154
155
156
157
158
159
# File 'lib/ievms/windows_guest.rb', line 149

def shutdown(quiet=false)
  log_stdout "Trying to shutdown ...", false if @verbose
  if powered_off?
    log_stdout "Already powered off.", false
  else
    log_stdout "shutting down ...", quiet
#        run_command_as_admin "shutdown.exe /s /f /t 0", quiet
    run_command "shutdown.exe /s /f /t 0", quiet
    wait_for_shutdown
  end
end

#start(quiet = false) ⇒ Object

start windows, finish as soon as boot is complete



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/ievms/windows_guest.rb', line 162

def start(quiet=false)
  if powered_off?
    log_stdout "starting ...", quiet

    if(@headless)
      type = 'headless'
    else
      type = 'gui'
    end
    `VBoxManage startvm "#{@vbox_name}" --type #{type}`
    wait_for_guestcontrol
  else
    log_stdout "Already started ...", quiet
  end
end

#upload_file_to_guest(local_path, guest_path, quiet = false) ⇒ Object

Upload a local file to the windows guest



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/ievms/windows_guest.rb', line 48

def upload_file_to_guest(local_path, guest_path, quiet=false)

  # 1 copy to tmp location in .ievms
  FileUtils.cp local_path, File.join(IEVMS_HOME,File.basename(local_path))

  # 2 run cp command in machine
  log_stdout "Copying #{local_path} to #{guest_path}", quiet
  guestcontrol_exec "cmd.exe", "cmd.exe /c copy \"E:\\#{File.basename(local_path)}\" \"#{guest_path}\""

  # 3 remove tmp file in .ievms
  FileUtils.rm File.join(IEVMS_HOME,File.basename(local_path))
end

#upload_file_to_guest_as_admin(local_path, guest_path, quiet = false) ⇒ Object

Upload a local file to the windows guest as Administator



89
90
91
92
93
94
95
96
# File 'lib/ievms/windows_guest.rb', line 89

def upload_file_to_guest_as_admin(local_path, guest_path, quiet=false)

  log_stdout "Copying #{local_path} to #{guest_path} as Administrator", quiet

  upload_file_to_guest(local_path, 'C:\Users\IEUser\.tempadminfile',true)
  run_command_as_admin('copy C:\Users\IEUser\.tempadminfile '+ guest_path,true)
  run_command 'del C:\Users\IEUser\.tempadminfile', true
end

#upload_string_as_file_to_guest(string, guest_path, quiet = false) ⇒ Object

make remote file from string



77
78
79
80
81
82
83
84
85
86
# File 'lib/ievms/windows_guest.rb', line 77

def upload_string_as_file_to_guest(string, guest_path, quiet=false)
  tmp = Tempfile.new('txtfile')
  tmp.write "#{string}\n"
  path = tmp.path
  tmp.rewind
  tmp.close

  upload_file_to_guest(path, guest_path, true)
  FileUtils.rm path
end