Skip to content

Instantly share code, notes, and snippets.

@smola
Last active June 5, 2017 16:04
Show Gist options
  • Save smola/bf2f87b4dd535a88549381671429e736 to your computer and use it in GitHub Desktop.
Save smola/bf2f87b4dd535a88549381671429e736 to your computer and use it in GitHub Desktop.
Enable WinRM on Windows 10 VM on VirtualBox
# 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
@smola
Copy link
Author

smola commented Jun 5, 2017

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment