Last active
June 5, 2017 16:04
-
-
Save smola/bf2f87b4dd535a88549381671429e736 to your computer and use it in GitHub Desktop.
Enable WinRM on Windows 10 VM on VirtualBox
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright © 2017 Santiago M. Mola | |
# Licensed under the terms of the MIT License. | |
# | |
# This script is a proof-of-concept to enable WinRM | |
# on Windows 10 (vagrant box Microsoft/EdgeOnWindows10). | |
# | |
# It borrows from the instructions by André Albino Pereira | |
# at https://gist.github.com/andreptb/57e388df5e881937e62a | |
# | |
# This is not considered stable and, in fact, I'm moving | |
# to a different approach. However, here's the PoC for future | |
# reference. | |
module VBox | |
class Machine | |
def initialize(id) | |
@id = id | |
end | |
@@scan_codes_per_command = 10 | |
# Scan code reference: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html | |
# These are for US keyboards. | |
@@scan_codes = { | |
# Ordinary scancodes | |
"Esc" => 0x01, | |
"1" => 0x02, # ! | |
"2" => 0x03, # @ | |
"3" => 0x04, # # | |
"4" => 0x05, # $ | |
"5" => 0x06, # % | |
"6" => 0x07, # ^ | |
"7" => 0x08, # & | |
"8" => 0x09, # * | |
"9" => 0x0A, # ( | |
"0" => 0x0B, # ) | |
"-" => 0x0C, # _ | |
"=" => 0x0D, # + | |
"Backspace" => 0x0E, | |
"Tab" => 0x0F, | |
"Q" => 0x10, | |
"W" => 0x11, | |
"E" => 0x12, | |
"R" => 0x13, | |
"T" => 0x14, | |
"Y" => 0x15, | |
"U" => 0x16, | |
"I" => 0x17, | |
"O" => 0x18, | |
"P" => 0x19, | |
"[" => 0x1A, # { | |
"]" => 0x1B, # } | |
"Enter" => 0x1C, | |
"LCtrl" => 0x1D, | |
"A" => 0x1E, | |
"S" => 0x1F, | |
"D" => 0x20, | |
"F" => 0x21, | |
"G" => 0x22, | |
"H" => 0x23, | |
"J" => 0x24, | |
"K" => 0x25, | |
"L" => 0x26, | |
";" => 0x27, # : | |
"'" => 0x28, # " | |
"`" => 0x29, # ~ | |
"LShift" => 0x2A, | |
"\\" => 0x2B, # | on a 102-key keyboard | |
"Z" => 0x2C, | |
"X" => 0x2D, | |
"C" => 0x2E, | |
"V" => 0x2F, | |
"B" => 0x30, | |
"N" => 0x31, | |
"M" => 0x32, | |
"," => 0x33, # < | |
"." => 0x34, # > | |
"/" => 0x35, # ? | |
"RShift" => 0x36, | |
# ... keypad ... | |
"LAlt" => 0x38, | |
"Space" => 0x39, | |
"CapsLock" => 0x3a, | |
"F1" => 0x3B, | |
"F2" => 0x3C, | |
"F3" => 0x3D, | |
"F4" => 0x3E, | |
"F5" => 0x3F, | |
"F6" => 0x40, | |
"F7" => 0x41, | |
"F8" => 0x42, | |
"F9" => 0x43, | |
"F10" => 0x44, | |
"NumLock" => 0x45, | |
"ScrollLockLock" => 0x46, | |
# ... keypad ... | |
# ... Alt-SysRq ... | |
# ... F11-F2 ... | |
# Escaped scancodes | |
# ... | |
"Up" => [0xE0, 0x48], | |
"Left" => [0xE0, 0x4B], | |
"Right" => [0xE0, 0x4D], | |
"Down" => [0xE0, 0x50], | |
# ... | |
"LeftWindow" => [0xE0, 0x5B] | |
# ... | |
} | |
@@shift_keys = { | |
"!" => "1", | |
"@" => "2", | |
"#" => "3", | |
"$" => "4", | |
"%" => "5", | |
"^" => "6", | |
"&" => "7", | |
"*" => "8", | |
"(" => "9", | |
")" => "0", | |
"_" => "-", | |
"+" => "=", | |
"{" => "[", | |
"}" => "]", | |
":" => ";", | |
"\"" => "'", | |
"~" => "`", | |
"<" => ",", | |
">" => ".", | |
"?" => "/" | |
} | |
def text_to_keys(text) | |
keys = [] | |
text.split("").each { |c| | |
if ('a'..'z').include?(c) | |
keys << c.upcase | |
elsif ('A'..'Z').include?(c) | |
keys << ["LShift", c.upcase] | |
elsif c == ' ' | |
keys << "Space" | |
elsif not @@shift_keys[c].nil? | |
keys << ["LShift", @@shift_keys[c]] | |
elsif not @@scan_codes[c].nil? | |
keys << c | |
else | |
raise Exception.new("Bad character: #{c}") | |
end | |
} | |
keys | |
end | |
def type_line(line) | |
self.type(self.text_to_keys(line) + ["Enter"]) | |
end | |
def type(keys) | |
scs = [] | |
keys.each { |k| | |
if k.kind_of?(Array) | |
scs += self.press_multi(k.map { |x| self.scan_code(x) }) | |
else | |
scs += self.press(self.scan_code(k)) | |
end | |
} | |
scs = scs.map { |sc| sc.to_s(16).rjust(2, "0") } | |
scs.each_slice(@@scan_codes_per_command).each { |sc| | |
cmd = "VBoxManage controlvm #{@id} keyboardputscancode #{sc.join(' ')}" | |
puts "Running: #{cmd}" | |
system(cmd) | |
} | |
end | |
def scan_code(k) | |
sc = @@scan_codes[k] | |
if sc.kind_of?(Array) | |
return sc | |
end | |
[sc] | |
end | |
def key_down(sc) | |
sc.dup | |
end | |
def key_up(sc) | |
sc = sc.dup | |
sc[-1] = sc[-1] + 0x80 | |
sc | |
end | |
def press(sc) | |
self.key_down(sc) + self.key_up(sc) | |
end | |
def press_multi(scs) | |
scs = scs.map { |sc| self.key_down(sc) } + scs.map { |sc| self.key_up(sc) } | |
scs.flatten | |
end | |
end | |
end | |
module VBox | |
class WindowsMachine | |
def initialize(id) | |
@vm = VBox::Machine.new(id) | |
end | |
def run(cmd) | |
@vm.type([["LeftWindow", "R"]]) | |
sleep(1) | |
@vm.type_line(cmd) | |
sleep(1) | |
end | |
def launch_powershell | |
self.run("powershell") | |
end | |
def ps_admin_powershell | |
@vm.type_line("Start-Process powershell -Verb runAs") | |
sleep(1) | |
@vm.type(["Left", "Enter"]) | |
sleep(1) | |
end | |
def provision_winrm() | |
self.launch_powershell | |
self.ps_admin_powershell | |
# Kudos to André Albino Pereira | |
# https://gist.github.com/andreptb/57e388df5e881937e62a | |
cmds = [ | |
"Set-NetConnectionProfile -NetworkCategory Private", | |
"winrm set winrm/config/winrs '@{MaxMemoryPerShellMB=\"300\"}'", | |
"winrm set winrm/config '@{MaxTimeoutms=\"1800000\"}'", | |
"winrm set winrm/config/client/auth '@{Basic=\"true\"}'", | |
"winrm set winrm/config/service '@{AllowUnencrypted=\"true\"}'", | |
"winrm set winrm/config/service/auth '@{Basic=\"true\"}'" | |
] | |
cmds.each { |cmd| | |
@vm.type_line(cmd) | |
sleep(1) | |
} | |
end | |
end | |
end | |
vm = VBox::WindowsMachine.new("vagrant-vnc_default_1496654467284_55302") | |
vm.provision_winrm |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For those who really want to get Windows running with Vagrant: it's probably better to use Packet to build a Windows Vagrant box from scratch: https://github.com/joefitzgerald/packer-windows