Overhaul the Hyper-V provider
This commit is contained in:
parent
dbba41a7ec
commit
e6457d5061
|
@ -47,13 +47,17 @@ module Vagrant
|
||||||
if opts.delete(:sudo) || opts.delete(:runas)
|
if opts.delete(:sudo) || opts.delete(:runas)
|
||||||
powerup_command(path, args, opts)
|
powerup_command(path, args, opts)
|
||||||
else
|
else
|
||||||
|
env = opts.delete(:env)
|
||||||
|
if env
|
||||||
|
env = env.map{|k,v| "$env:#{k}=#{v}"}.join(";") + "; "
|
||||||
|
end
|
||||||
command = [
|
command = [
|
||||||
executable,
|
executable,
|
||||||
"-NoLogo",
|
"-NoLogo",
|
||||||
"-NoProfile",
|
"-NoProfile",
|
||||||
"-NonInteractive",
|
"-NonInteractive",
|
||||||
"-ExecutionPolicy", "Bypass",
|
"-ExecutionPolicy", "Bypass",
|
||||||
"&('#{path}')",
|
"#{env}&('#{path}')",
|
||||||
args
|
args
|
||||||
].flatten
|
].flatten
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,8 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
b2.use Provision
|
b2.use Provision
|
||||||
|
b2.use Configure
|
||||||
|
b2.use SetName
|
||||||
b2.use NetSetVLan
|
b2.use NetSetVLan
|
||||||
b2.use NetSetMac
|
b2.use NetSetMac
|
||||||
b2.use StartInstance
|
b2.use StartInstance
|
||||||
|
@ -288,6 +290,7 @@ module VagrantPlugins
|
||||||
autoload :Export, action_root.join("export")
|
autoload :Export, action_root.join("export")
|
||||||
|
|
||||||
autoload :CheckEnabled, action_root.join("check_enabled")
|
autoload :CheckEnabled, action_root.join("check_enabled")
|
||||||
|
autoload :Configure, action_root.join("configure")
|
||||||
autoload :DeleteVM, action_root.join("delete_vm")
|
autoload :DeleteVM, action_root.join("delete_vm")
|
||||||
autoload :Import, action_root.join("import")
|
autoload :Import, action_root.join("import")
|
||||||
autoload :Package, action_root.join("package")
|
autoload :Package, action_root.join("package")
|
||||||
|
@ -304,6 +307,7 @@ module VagrantPlugins
|
||||||
autoload :SnapshotDelete, action_root.join("snapshot_delete")
|
autoload :SnapshotDelete, action_root.join("snapshot_delete")
|
||||||
autoload :SnapshotRestore, action_root.join("snapshot_restore")
|
autoload :SnapshotRestore, action_root.join("snapshot_restore")
|
||||||
autoload :SnapshotSave, action_root.join("snapshot_save")
|
autoload :SnapshotSave, action_root.join("snapshot_save")
|
||||||
|
autoload :SetName, action_root.join("set_name")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
require "fileutils"
|
||||||
|
|
||||||
|
require "log4r"
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module HyperV
|
||||||
|
module Action
|
||||||
|
class Configure
|
||||||
|
def initialize(app, env)
|
||||||
|
@app = app
|
||||||
|
@logger = Log4r::Logger.new("vagrant::hyperv::configure")
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
switches = env[:machine].provider.driver.execute(:get_switches)
|
||||||
|
if switches.empty?
|
||||||
|
raise Errors::NoSwitches
|
||||||
|
end
|
||||||
|
|
||||||
|
switch = nil
|
||||||
|
env[:machine].config.vm.networks.each do |type, opts|
|
||||||
|
next if type != :public_network && type != :private_network
|
||||||
|
|
||||||
|
if opts[:bridge]
|
||||||
|
@logger.debug("Looking for switch with name or ID: #{opts[:bridge]}")
|
||||||
|
switch = switches.find{ |s|
|
||||||
|
s["Name"].downcase == opts[:bridge] ||
|
||||||
|
s["Id"].downcase == opts[:bridge]
|
||||||
|
}
|
||||||
|
if switch
|
||||||
|
@logger.debug("Found switch - Name: #{switch["Name"]} ID: #{switch["Id"]}")
|
||||||
|
switch = switch["Id"]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# If we already configured previously don't prompt for switch
|
||||||
|
sentinel = env[:machine].data_dir.join("action_configure")
|
||||||
|
|
||||||
|
if !switch && !sentinel.file?
|
||||||
|
if switches.length > 1
|
||||||
|
env[:ui].detail(I18n.t("vagrant_hyperv.choose_switch") + "\n ")
|
||||||
|
switches.each_index do |i|
|
||||||
|
switch = switches[i]
|
||||||
|
env[:ui].detail("#{i+1}) #{switch["Name"]}")
|
||||||
|
end
|
||||||
|
env[:ui].detail(" ")
|
||||||
|
|
||||||
|
switch = nil
|
||||||
|
while !switch
|
||||||
|
switch = env[:ui].ask("What switch would you like to use? ")
|
||||||
|
next if !switch
|
||||||
|
switch = switch.to_i - 1
|
||||||
|
switch = nil if switch < 0 || switch >= switches.length
|
||||||
|
end
|
||||||
|
switch = switches[switch]["Id"]
|
||||||
|
else
|
||||||
|
switch = switches.first["Id"]
|
||||||
|
@logger.debug("Only single switch available so using that.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
options = {
|
||||||
|
"VMID" => env[:machine].id,
|
||||||
|
"SwitchID" => switch,
|
||||||
|
"Memory" => env[:machine].provider_config.memory,
|
||||||
|
"MaxMemory" => env[:machine].provider_config.maxmemory,
|
||||||
|
"Processors" => env[:machine].provider_config.cpus,
|
||||||
|
"AutoStartAction" => env[:machine].provider_config.auto_start_action,
|
||||||
|
"AutoStopAction" => env[:machine].provider_config.auto_stop_action,
|
||||||
|
"EnableCheckpoints" => env[:machine].provider_config.enable_checkpoints,
|
||||||
|
"VirtualizationExtensions" => !!env[:machine].provider_config.enable_virtualization_extensions,
|
||||||
|
}
|
||||||
|
options.delete_if{|_,v| v.nil? }
|
||||||
|
|
||||||
|
env[:ui].detail("Configuring the VM...")
|
||||||
|
env[:machine].provider.driver.execute(:configure_vm, options)
|
||||||
|
|
||||||
|
# Create the sentinel
|
||||||
|
sentinel.open("w") do |f|
|
||||||
|
f.write(Time.now.to_i.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
if env[:machine].provider_config.vm_integration_services
|
||||||
|
env[:ui].detail("Setting VM Integration Services")
|
||||||
|
|
||||||
|
env[:machine].provider_config.vm_integration_services.each do |key, value|
|
||||||
|
state = value ? "enabled" : "disabled"
|
||||||
|
env[:ui].output("#{key} is #{state}")
|
||||||
|
end
|
||||||
|
|
||||||
|
env[:machine].provider.driver.set_vm_integration_services(
|
||||||
|
env[:machine].provider_config.vm_integration_services)
|
||||||
|
end
|
||||||
|
|
||||||
|
@app.call(env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,11 +1,13 @@
|
||||||
require "fileutils"
|
require "fileutils"
|
||||||
|
|
||||||
require "log4r"
|
require "log4r"
|
||||||
|
|
||||||
module VagrantPlugins
|
module VagrantPlugins
|
||||||
module HyperV
|
module HyperV
|
||||||
module Action
|
module Action
|
||||||
class Import
|
class Import
|
||||||
|
|
||||||
|
VALID_HD_EXTENSIONS = [".vhd".freeze, ".vhdx".freeze].freeze
|
||||||
|
|
||||||
def initialize(app, env)
|
def initialize(app, env)
|
||||||
@app = app
|
@app = app
|
||||||
@logger = Log4r::Logger.new("vagrant::hyperv::import")
|
@logger = Log4r::Logger.new("vagrant::hyperv::import")
|
||||||
|
@ -14,160 +16,64 @@ module VagrantPlugins
|
||||||
def call(env)
|
def call(env)
|
||||||
vm_dir = env[:machine].box.directory.join("Virtual Machines")
|
vm_dir = env[:machine].box.directory.join("Virtual Machines")
|
||||||
hd_dir = env[:machine].box.directory.join("Virtual Hard Disks")
|
hd_dir = env[:machine].box.directory.join("Virtual Hard Disks")
|
||||||
memory = env[:machine].provider_config.memory
|
|
||||||
maxmemory = env[:machine].provider_config.maxmemory
|
|
||||||
cpus = env[:machine].provider_config.cpus
|
|
||||||
vmname = env[:machine].provider_config.vmname
|
|
||||||
differencing_disk = env[:machine].provider_config.differencing_disk
|
|
||||||
auto_start_action = env[:machine].provider_config.auto_start_action
|
|
||||||
auto_stop_action = env[:machine].provider_config.auto_stop_action
|
|
||||||
enable_virtualization_extensions = env[:machine].provider_config.enable_virtualization_extensions
|
|
||||||
vm_integration_services = env[:machine].provider_config.vm_integration_services
|
|
||||||
|
|
||||||
env[:ui].output("Configured Dynamic memory allocation, maxmemory is #{maxmemory}") if maxmemory
|
|
||||||
env[:ui].output("Configured startup memory is #{memory}") if memory
|
|
||||||
env[:ui].output("Configured cpus number is #{cpus}") if cpus
|
|
||||||
env[:ui].output("Configured enable virtualization extensions is #{enable_virtualization_extensions}") if enable_virtualization_extensions
|
|
||||||
env[:ui].output("Configured vmname is #{vmname}") if vmname
|
|
||||||
env[:ui].output("Configured differencing disk instead of cloning") if differencing_disk
|
|
||||||
env[:ui].output("Configured automatic start action is #{auto_start_action}") if auto_start_action
|
|
||||||
env[:ui].output("Configured automatic stop action is #{auto_stop_action}") if auto_stop_action
|
|
||||||
|
|
||||||
if !vm_dir.directory? || !hd_dir.directory?
|
if !vm_dir.directory? || !hd_dir.directory?
|
||||||
|
@logger.error("Required virtual machine directory not found!")
|
||||||
raise Errors::BoxInvalid
|
raise Errors::BoxInvalid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
valid_config_ext = [".xml"]
|
||||||
|
if env[:machine].provider.driver.has_vmcx_support?
|
||||||
|
valid_config_ext << ".vmcx"
|
||||||
|
end
|
||||||
|
|
||||||
config_path = nil
|
config_path = nil
|
||||||
config_type = nil
|
vm_dir.each_child do |file|
|
||||||
vm_dir.each_child do |f|
|
if valid_config_ext.include?(file.extname.downcase)
|
||||||
if f.extname.downcase == '.xml'
|
config_path = file
|
||||||
@logger.debug("Found XML config...")
|
|
||||||
config_path = f
|
|
||||||
config_type = 'xml'
|
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
vmcx_support = env[:machine].provider.driver.execute("has_vmcx_support.ps1", {})['result']
|
if !config_path
|
||||||
if vmcx_support
|
@logger.error("Failed to locate box configuration path")
|
||||||
vm_dir.each_child do |f|
|
raise Errors::BoxInvalid
|
||||||
if f.extname.downcase == '.vmcx'
|
else
|
||||||
@logger.debug("Found VMCX config and support...")
|
@logger.info("Found box configuration path: #{config_path}")
|
||||||
config_path = f
|
|
||||||
config_type = 'vmcx'
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
image_path = nil
|
image_path = nil
|
||||||
image_ext = nil
|
hd_dir.each_child do |file|
|
||||||
image_filename = nil
|
if VALID_HD_EXTENSIONS.include?(file.extname.downcase)
|
||||||
hd_dir.each_child do |f|
|
image_path = file
|
||||||
if %w{.vhd .vhdx}.include?(f.extname.downcase)
|
|
||||||
image_path = f
|
|
||||||
image_ext = f.extname.downcase
|
|
||||||
image_filename = File.basename(f, image_ext)
|
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !config_path || !image_path
|
if !image_path
|
||||||
|
@logger.error("Failed to locate box image path")
|
||||||
raise Errors::BoxInvalid
|
raise Errors::BoxInvalid
|
||||||
|
else
|
||||||
|
@logger.info("Found box image path: #{image_path}")
|
||||||
end
|
end
|
||||||
|
|
||||||
env[:ui].output("Importing a Hyper-V instance")
|
env[:ui].output("Importing a Hyper-V instance")
|
||||||
|
dest_path = env[:machine].data_dir.join("Virtual Hard Disks").join(image_path.basename).to_s
|
||||||
|
|
||||||
switches = env[:machine].provider.driver.execute("get_switches.ps1", {})
|
|
||||||
raise Errors::NoSwitches if switches.empty?
|
|
||||||
|
|
||||||
switch = nil
|
|
||||||
env[:machine].config.vm.networks.each do |type, opts|
|
|
||||||
next if type != :public_network && type != :private_network
|
|
||||||
|
|
||||||
switchToFind = opts[:bridge]
|
|
||||||
|
|
||||||
if switchToFind
|
|
||||||
@logger.debug("Looking for switch with name: #{switchToFind}")
|
|
||||||
switch = switches.find { |s| s["Name"].downcase == switchToFind.downcase }["Id"]
|
|
||||||
@logger.debug("Found switch: #{switch}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if switch.nil?
|
|
||||||
if switches.length > 1
|
|
||||||
env[:ui].detail(I18n.t("vagrant_hyperv.choose_switch") + "\n ")
|
|
||||||
switches.each_index do |i|
|
|
||||||
switch = switches[i]
|
|
||||||
env[:ui].detail("#{i+1}) #{switch["Name"]}")
|
|
||||||
end
|
|
||||||
env[:ui].detail(" ")
|
|
||||||
|
|
||||||
switch = nil
|
|
||||||
while !switch
|
|
||||||
switch = env[:ui].ask("What switch would you like to use? ")
|
|
||||||
next if !switch
|
|
||||||
switch = switch.to_i - 1
|
|
||||||
switch = nil if switch < 0 || switch >= switches.length
|
|
||||||
end
|
|
||||||
switch = switches[switch]["Id"]
|
|
||||||
else
|
|
||||||
switch = switches[0]["Id"]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
env[:ui].detail("Cloning virtual hard drive...")
|
|
||||||
source_path = image_path.to_s
|
|
||||||
dest_path = env[:machine].data_dir.join("Virtual Hard Disks").join("#{image_filename}#{image_ext}").to_s
|
|
||||||
|
|
||||||
# Still hard copy the disk of old XML configurations
|
|
||||||
if config_type == 'xml'
|
|
||||||
if differencing_disk
|
|
||||||
env[:machine].provider.driver.execute("clone_vhd.ps1", {Source: source_path, Destination: dest_path})
|
|
||||||
else
|
|
||||||
FileUtils.mkdir_p(env[:machine].data_dir.join("Virtual Hard Disks"))
|
|
||||||
FileUtils.cp(source_path, dest_path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
image_path = dest_path
|
|
||||||
|
|
||||||
# We have to normalize the paths to be Windows paths since
|
|
||||||
# we're executing PowerShell.
|
|
||||||
options = {
|
options = {
|
||||||
vm_config_file: config_path.to_s.gsub("/", "\\"),
|
"VMConfigFile" => config_path.to_s.gsub("/", "\\"),
|
||||||
vm_config_type: config_type,
|
"DestinationPath" => dest_path.to_s.gsub("/", "\\"),
|
||||||
source_path: source_path.to_s,
|
"DataPath" => env[:machine].data_dir.to_s.gsub("/", "\\"),
|
||||||
dest_path: dest_path,
|
"LinkedClone" => !!env[:machine].provider_config.linked_clone,
|
||||||
data_path: env[:machine].data_dir.to_s.gsub("/", "\\")
|
"SourcePath" => image_path.to_s.gsub("/", "\\"),
|
||||||
|
"VMName" => env[:machine].provider_config.vmname,
|
||||||
}
|
}
|
||||||
options[:switchid] = switch if switch
|
|
||||||
options[:memory] = memory if memory
|
|
||||||
options[:maxmemory] = maxmemory if maxmemory
|
|
||||||
options[:cpus] = cpus if cpus
|
|
||||||
options[:vmname] = vmname if vmname
|
|
||||||
options[:auto_start_action] = auto_start_action if auto_start_action
|
|
||||||
options[:auto_stop_action] = auto_stop_action if auto_stop_action
|
|
||||||
options[:differencing_disk] = differencing_disk if differencing_disk
|
|
||||||
options[:enable_virtualization_extensions] = "True" if enable_virtualization_extensions and enable_virtualization_extensions == true
|
|
||||||
|
|
||||||
env[:ui].detail("Creating and registering the VM...")
|
env[:ui].detail("Creating and registering the VM...")
|
||||||
server = env[:machine].provider.driver.import(options)
|
server = env[:machine].provider.driver.import(options)
|
||||||
|
|
||||||
env[:ui].detail("Setting VM Integration Services")
|
env[:ui].detail("Successfully imported VM")
|
||||||
vm_integration_services.each do |key, value|
|
|
||||||
state = false
|
|
||||||
if value === true
|
|
||||||
state = "enabled"
|
|
||||||
elsif value === false
|
|
||||||
state = "disabled"
|
|
||||||
end
|
|
||||||
env[:ui].output("#{key} is #{state}") if state
|
|
||||||
end
|
|
||||||
|
|
||||||
vm_integration_services[:VmId] = server["id"]
|
|
||||||
env[:machine].provider.driver.set_vm_integration_services(vm_integration_services)
|
|
||||||
|
|
||||||
env[:ui].detail("Successfully imported a VM with name: #{server['name']}")
|
|
||||||
env[:machine].id = server["id"]
|
env[:machine].id = server["id"]
|
||||||
@app.call(env)
|
@app.call(env)
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
require "log4r"
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module HyperV
|
||||||
|
module Action
|
||||||
|
class SetName
|
||||||
|
def initialize(app, env)
|
||||||
|
@app = app
|
||||||
|
@logger = Log4r::Logger.new("vagrant::hyperv::set_name")
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
name = env[:machine].provider_config.vmname
|
||||||
|
|
||||||
|
# If we already set the name before, then don't do anything
|
||||||
|
sentinel = env[:machine].data_dir.join("action_set_name")
|
||||||
|
if !name && sentinel.file?
|
||||||
|
@logger.info("Default name was already set before, not doing it again.")
|
||||||
|
return @app.call(env)
|
||||||
|
end
|
||||||
|
|
||||||
|
# If no name was manually set, then use a default
|
||||||
|
if !name
|
||||||
|
prefix = "#{env[:root_path].basename.to_s}_#{env[:machine].name}"
|
||||||
|
prefix.gsub!(/[^-a-z0-9_]/i, "")
|
||||||
|
|
||||||
|
# milliseconds + random number suffix to allow for simultaneous
|
||||||
|
# `vagrant up` of the same box in different dirs
|
||||||
|
name = prefix + "_#{(Time.now.to_f * 1000.0).to_i}_#{rand(100000)}"
|
||||||
|
end
|
||||||
|
|
||||||
|
env[:machine].provider.driver.set_name(name)
|
||||||
|
|
||||||
|
# Create the sentinel
|
||||||
|
sentinel.open("w") do |f|
|
||||||
|
f.write(Time.now.to_i.to_s)
|
||||||
|
end
|
||||||
|
@app.call(env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,18 +3,49 @@ require "vagrant"
|
||||||
module VagrantPlugins
|
module VagrantPlugins
|
||||||
module HyperV
|
module HyperV
|
||||||
class Config < Vagrant.plugin("2", :config)
|
class Config < Vagrant.plugin("2", :config)
|
||||||
attr_accessor :ip_address_timeout # Time to wait for an IP address when booting, in seconds @return [Integer]
|
# Allowed automatic start actions for VM
|
||||||
attr_accessor :memory # Memory size in mb @return [Integer]
|
ALLOWED_AUTO_START_ACTIONS = [
|
||||||
attr_accessor :maxmemory # Maximal memory size in mb enables dynamical memory allocation @return [Integer]
|
"Nothing".freeze,
|
||||||
attr_accessor :cpus # Number of cpu's @return [Integer]
|
"StartIfRunning".freeze,
|
||||||
attr_accessor :vmname # Name that will be shoen in Hyperv Manager @return [String]
|
"Start".freeze
|
||||||
attr_accessor :vlan_id # VLAN ID for network interface for the virtual machine. @return [Integer]
|
].freeze
|
||||||
attr_accessor :mac # MAC address for network interface for the virtual machine. @return [String]
|
|
||||||
attr_accessor :differencing_disk # Create differencing disk instead of cloning whole VHD [Boolean]
|
# Allowed automatic stop actions for VM
|
||||||
attr_accessor :auto_start_action #action on automatic start of VM. Values: Nothing, StartIfRunning, Start
|
ALLOWED_AUTO_STOP_ACTIONS = [
|
||||||
attr_accessor :auto_stop_action #action on automatic stop of VM. Values: ShutDown, TurnOff, Save
|
"ShutDown".freeze,
|
||||||
attr_accessor :enable_virtualization_extensions # Enable virtualization extensions (nested virtualization). Values: true, false
|
"TurnOff".freeze,
|
||||||
attr_accessor :vm_integration_services # Options for VMServiceIntegration [Hash]
|
"Save".freeze
|
||||||
|
].freeze
|
||||||
|
|
||||||
|
# @return [Integer] Seconds to wait for an IP address when booting
|
||||||
|
attr_accessor :ip_address_timeout
|
||||||
|
# @return [Integer] Memory size in MB
|
||||||
|
attr_accessor :memory
|
||||||
|
# @return [Integer] Maximum memory size in MB. Enables dynamic memory.
|
||||||
|
attr_accessor :maxmemory
|
||||||
|
# @return [Integer] Number of CPUs
|
||||||
|
attr_accessor :cpus
|
||||||
|
# @return [String] Name of the VM (Shown in the Hyper-V Manager)
|
||||||
|
attr_accessor :vmname
|
||||||
|
# @return [Integer] VLAN ID for network interface
|
||||||
|
attr_accessor :vlan_id
|
||||||
|
# @return [String] MAC address for network interface
|
||||||
|
attr_accessor :mac
|
||||||
|
# @return [Boolean] Create linked clone instead of full clone
|
||||||
|
# @note **DEPRECATED** use #linked_clone instead
|
||||||
|
attr_accessor :differencing_disk
|
||||||
|
# @return [Boolean] Create linked clone instead of full clone
|
||||||
|
attr_accessor :linked_clone
|
||||||
|
# @return [String] Automatic action on start of host. Default: Nothing (Nothing, StartIfRunning, Start)
|
||||||
|
attr_accessor :auto_start_action
|
||||||
|
# @return [String] Automatic action on stop of host. Default: ShutDown (ShutDown, TurnOff, Save)
|
||||||
|
attr_accessor :auto_stop_action
|
||||||
|
# @return [Boolean] Enable automatic checkpoints. Default: false
|
||||||
|
attr_accessor :enable_checkpoints
|
||||||
|
# @return [Boolean] Enable virtualization extensions
|
||||||
|
attr_accessor :enable_virtualization_extensions
|
||||||
|
# @return [Hash] Options for VMServiceIntegration
|
||||||
|
attr_accessor :vm_integration_services
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@ip_address_timeout = UNSET_VALUE
|
@ip_address_timeout = UNSET_VALUE
|
||||||
|
@ -24,10 +55,12 @@ module VagrantPlugins
|
||||||
@vmname = UNSET_VALUE
|
@vmname = UNSET_VALUE
|
||||||
@vlan_id = UNSET_VALUE
|
@vlan_id = UNSET_VALUE
|
||||||
@mac = UNSET_VALUE
|
@mac = UNSET_VALUE
|
||||||
|
@linked_clone = UNSET_VALUE
|
||||||
@differencing_disk = UNSET_VALUE
|
@differencing_disk = UNSET_VALUE
|
||||||
@auto_start_action = UNSET_VALUE
|
@auto_start_action = UNSET_VALUE
|
||||||
@auto_stop_action = UNSET_VALUE
|
@auto_stop_action = UNSET_VALUE
|
||||||
@enable_virtualization_extensions = UNSET_VALUE
|
@enable_virtualization_extensions = UNSET_VALUE
|
||||||
|
@enable_checkpoints = UNSET_VALUE
|
||||||
@vm_integration_services = {
|
@vm_integration_services = {
|
||||||
guest_service_interface: UNSET_VALUE,
|
guest_service_interface: UNSET_VALUE,
|
||||||
heartbeat: UNSET_VALUE,
|
heartbeat: UNSET_VALUE,
|
||||||
|
@ -39,6 +72,10 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
def finalize!
|
def finalize!
|
||||||
|
@linked_clone = false if @linked_clone == UNSET_VALUE
|
||||||
|
@differencing_disk = false if @differencing_disk == UNSET_VALUE
|
||||||
|
@linked_clone ||= @differencing_disk
|
||||||
|
@differencing_disk ||= @linked_clone
|
||||||
if @ip_address_timeout == UNSET_VALUE
|
if @ip_address_timeout == UNSET_VALUE
|
||||||
@ip_address_timeout = 120
|
@ip_address_timeout = 120
|
||||||
end
|
end
|
||||||
|
@ -48,20 +85,32 @@ module VagrantPlugins
|
||||||
@vmname = nil if @vmname == UNSET_VALUE
|
@vmname = nil if @vmname == UNSET_VALUE
|
||||||
@vlan_id = nil if @vlan_id == UNSET_VALUE
|
@vlan_id = nil if @vlan_id == UNSET_VALUE
|
||||||
@mac = nil if @mac == UNSET_VALUE
|
@mac = nil if @mac == UNSET_VALUE
|
||||||
@differencing_disk = false if @differencing_disk == UNSET_VALUE
|
|
||||||
@auto_start_action = nil if @auto_start_action == UNSET_VALUE
|
|
||||||
@auto_stop_action = nil if @auto_stop_action == UNSET_VALUE
|
|
||||||
@enable_virtualization_extensions = false if @enable_virtualization_extensions == UNSET_VALUE # TODO will this work?
|
|
||||||
|
|
||||||
@vm_integration_services.each { |key, value|
|
@auto_start_action = "Nothing" if @auto_start_action == UNSET_VALUE
|
||||||
@vm_integration_services[key] = nil if value == UNSET_VALUE
|
@auto_stop_action = "ShutDown" if @auto_stop_action == UNSET_VALUE
|
||||||
}
|
@enable_virtualization_extensions = false if @enable_virtualization_extensions == UNSET_VALUE
|
||||||
@vm_integration_services = nil if @vm_integration_services.length == 0
|
if @enable_checkpoints == UNSET_VALUE
|
||||||
|
@enable_checkpoints = false
|
||||||
|
else
|
||||||
|
@enable_checkpoints = !!@enable_checkpoints
|
||||||
|
end
|
||||||
|
@vm_integration_services.delete_if{|_, v| v == UNSET_VALUE }
|
||||||
|
@vm_integration_services = nil if @vm_integration_services.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate(machine)
|
def validate(machine)
|
||||||
errors = _detected_errors
|
errors = _detected_errors
|
||||||
|
|
||||||
|
if !ALLOWED_AUTO_START_ACTIONS.include?(auto_start_action)
|
||||||
|
errors << I18n.t("vagrant.hyperv.config.invalid_auto_start_action", action: auto_start_action,
|
||||||
|
allowed_actions: ALLOWED_AUTO_START_ACTIONS.join(", "))
|
||||||
|
end
|
||||||
|
|
||||||
|
if !ALLOWED_AUTO_STOP_ACTIONS.include?(auto_stop_action)
|
||||||
|
errors << I18n.t("vagrant.hyperv.config.invalid_auto_stop_action", action: auto_stop_action,
|
||||||
|
allowed_actions: ALLOWED_AUTO_STOP_ACTIONS.join(", "))
|
||||||
|
end
|
||||||
|
|
||||||
{"Hyper-V" => errors}
|
{"Hyper-V" => errors}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,19 +10,41 @@ module VagrantPlugins
|
||||||
ERROR_REGEXP = /===Begin-Error===(.+?)===End-Error===/m
|
ERROR_REGEXP = /===Begin-Error===(.+?)===End-Error===/m
|
||||||
OUTPUT_REGEXP = /===Begin-Output===(.+?)===End-Output===/m
|
OUTPUT_REGEXP = /===Begin-Output===(.+?)===End-Output===/m
|
||||||
|
|
||||||
|
# Name mapping for integration services for nicer keys
|
||||||
|
INTEGRATION_SERVICES_MAP = {
|
||||||
|
guest_service_interface: "Guest Service Interface",
|
||||||
|
heartbeat: "Heartbeat",
|
||||||
|
key_value_pair_exchange: "Key-Value Pair Exchange",
|
||||||
|
shutdown: "Shutdown",
|
||||||
|
time_synchronization: "Time Synchronization",
|
||||||
|
vss: "VSS",
|
||||||
|
}
|
||||||
|
|
||||||
|
# @return [String] VM ID
|
||||||
attr_reader :vm_id
|
attr_reader :vm_id
|
||||||
|
|
||||||
def initialize(id)
|
def initialize(id)
|
||||||
@vm_id = id
|
@vm_id = id
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute(path, options)
|
# @return [Boolean] Supports VMCX
|
||||||
r = execute_powershell(path, options)
|
def has_vmcx_support?
|
||||||
if r.exit_code != 0
|
!!execute(:has_vmcx_support)["result"]
|
||||||
raise Errors::PowerShellError,
|
end
|
||||||
script: path,
|
|
||||||
stderr: r.stderr
|
# Execute a PowerShell command and process the results
|
||||||
|
#
|
||||||
|
# @param [String] path Path to PowerShell script
|
||||||
|
# @param [Hash] options Options to pass to command
|
||||||
|
#
|
||||||
|
# @return [Object, nil] If the command returned JSON content
|
||||||
|
# it will be parsed and returned, otherwise
|
||||||
|
# nil will be returned
|
||||||
|
def execute(path, options={})
|
||||||
|
if path.is_a?(Symbol)
|
||||||
|
path = "#{path}.ps1"
|
||||||
end
|
end
|
||||||
|
r = execute_powershell(path, options)
|
||||||
|
|
||||||
# We only want unix-style line endings within Vagrant
|
# We only want unix-style line endings within Vagrant
|
||||||
r.stdout.gsub!("\r\n", "\n")
|
r.stdout.gsub!("\r\n", "\n")
|
||||||
|
@ -40,104 +62,185 @@ module VagrantPlugins
|
||||||
stderr: data["error"]
|
stderr: data["error"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if r.exit_code != 0
|
||||||
|
raise Errors::PowerShellError,
|
||||||
|
script: path,
|
||||||
|
stderr: r.stderr
|
||||||
|
end
|
||||||
|
|
||||||
# Nothing
|
# Nothing
|
||||||
return nil if !output_match
|
return nil if !output_match
|
||||||
return JSON.parse(output_match[1])
|
return JSON.parse(output_match[1])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Fetch current state of the VM
|
||||||
|
#
|
||||||
|
# @return [Hash<state, status>]
|
||||||
def get_current_state
|
def get_current_state
|
||||||
execute('get_vm_status.ps1', { VmId: vm_id })
|
execute(:get_vm_status, { VmId: vm_id })
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_vm
|
# Delete the VM
|
||||||
execute('delete_vm.ps1', { VmId: vm_id })
|
#
|
||||||
end
|
# @return [nil]
|
||||||
|
def delete_vm
|
||||||
|
execute(:delete_vm, { VmId: vm_id })
|
||||||
|
end
|
||||||
|
|
||||||
|
# Export the VM to the given path
|
||||||
|
#
|
||||||
|
# @param [String] path Path for export
|
||||||
|
# @return [nil]
|
||||||
def export(path)
|
def export(path)
|
||||||
execute('export_vm.ps1', {VmId: vm_id, Path: path})
|
execute(:export_vm, {VmId: vm_id, Path: path})
|
||||||
end
|
end
|
||||||
|
|
||||||
def read_guest_ip
|
# Get the IP address of the VM
|
||||||
execute('get_network_config.ps1', { VmId: vm_id })
|
#
|
||||||
end
|
# @return [Hash<ip>]
|
||||||
|
def read_guest_ip
|
||||||
|
execute(:get_network_config, { VmId: vm_id })
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get the MAC address of the VM
|
||||||
|
#
|
||||||
|
# @return [Hash<mac>]
|
||||||
def read_mac_address
|
def read_mac_address
|
||||||
execute('get_network_mac.ps1', { VmId: vm_id })
|
execute(:get_network_mac, { VmId: vm_id })
|
||||||
end
|
end
|
||||||
|
|
||||||
def resume
|
# Resume the VM from suspension
|
||||||
execute('resume_vm.ps1', { VmId: vm_id })
|
#
|
||||||
end
|
# @return [nil]
|
||||||
|
def resume
|
||||||
|
execute(:resume_vm, { VmId: vm_id })
|
||||||
|
end
|
||||||
|
|
||||||
def start
|
# Start the VM
|
||||||
execute('start_vm.ps1', { VmId: vm_id })
|
#
|
||||||
end
|
# @return [nil]
|
||||||
|
def start
|
||||||
|
execute(:start_vm, { VmId: vm_id })
|
||||||
|
end
|
||||||
|
|
||||||
def stop
|
# Stop the VM
|
||||||
execute('stop_vm.ps1', { VmId: vm_id })
|
#
|
||||||
end
|
# @return [nil]
|
||||||
|
def stop
|
||||||
|
execute(:stop_vm, { VmId: vm_id })
|
||||||
|
end
|
||||||
|
|
||||||
def suspend
|
# Suspend the VM
|
||||||
execute("suspend_vm.ps1", { VmId: vm_id })
|
#
|
||||||
end
|
# @return [nil]
|
||||||
|
def suspend
|
||||||
|
execute(:suspend_vm, { VmId: vm_id })
|
||||||
|
end
|
||||||
|
|
||||||
def import(options)
|
# Import a new VM
|
||||||
config_type = options.delete(:vm_config_type)
|
#
|
||||||
if config_type === "vmcx"
|
# @param [Hash] options Configuration options
|
||||||
execute('import_vm_vmcx.ps1', options)
|
# @return [Hash<id>] New VM ID
|
||||||
else
|
def import(options)
|
||||||
options.delete(:data_path)
|
execute(:import_vm, options)
|
||||||
options.delete(:source_path)
|
end
|
||||||
options.delete(:differencing_disk)
|
|
||||||
execute('import_vm_xml.ps1', options)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def net_set_vlan(vlan_id)
|
# Set the VLAN ID
|
||||||
execute("set_network_vlan.ps1", { VmId: vm_id, VlanId: vlan_id })
|
#
|
||||||
end
|
# @param [String] vlan_id VLAN ID
|
||||||
|
# @return [nil]
|
||||||
|
def net_set_vlan(vlan_id)
|
||||||
|
execute(:set_network_vlan, { VmId: vm_id, VlanId: vlan_id })
|
||||||
|
end
|
||||||
|
|
||||||
def net_set_mac(mac_addr)
|
# Set the VM adapter MAC address
|
||||||
execute("set_network_mac.ps1", { VmId: vm_id, Mac: mac_addr })
|
#
|
||||||
end
|
# @param [String] mac_addr MAC address
|
||||||
|
# @return [nil]
|
||||||
|
def net_set_mac(mac_addr)
|
||||||
|
execute(:set_network_mac, { VmId: vm_id, Mac: mac_addr })
|
||||||
|
end
|
||||||
|
|
||||||
def create_snapshot(snapshot_name)
|
# Create a new snapshot with the given name
|
||||||
execute("create_snapshot.ps1", { VmId: vm_id, SnapName: (snapshot_name) } )
|
#
|
||||||
end
|
# @param [String] snapshot_name Name of the new snapshot
|
||||||
|
# @return [nil]
|
||||||
|
def create_snapshot(snapshot_name)
|
||||||
|
execute(:create_snapshot, { VmId: vm_id, SnapName: (snapshot_name) } )
|
||||||
|
end
|
||||||
|
|
||||||
def restore_snapshot(snapshot_name)
|
# Restore the given snapshot
|
||||||
execute("restore_snapshot.ps1", { VmId: vm_id, SnapName: (snapshot_name) } )
|
#
|
||||||
end
|
# @param [String] snapshot_name Name of snapshot to restore
|
||||||
|
# @return [nil]
|
||||||
|
def restore_snapshot(snapshot_name)
|
||||||
|
execute(:restore_snapshot, { VmId: vm_id, SnapName: (snapshot_name) } )
|
||||||
|
end
|
||||||
|
|
||||||
def list_snapshots()
|
# Get list of current snapshots
|
||||||
snaps = execute("list_snapshots.ps1", { VmID: vm_id } )
|
#
|
||||||
snaps.map { |s| s['Name'] }
|
# @return [Array<String>] snapshot names
|
||||||
end
|
def list_snapshots
|
||||||
|
snaps = execute(:list_snapshots, { VmID: vm_id } )
|
||||||
|
snaps.map { |s| s['Name'] }
|
||||||
|
end
|
||||||
|
|
||||||
def delete_snapshot(snapshot_name)
|
# Delete snapshot with the given name
|
||||||
execute("delete_snapshot.ps1", {VmID: vm_id, SnapName: snapshot_name})
|
#
|
||||||
end
|
# @param [String] snapshot_name Name of snapshot to delete
|
||||||
|
# @return [nil]
|
||||||
|
def delete_snapshot(snapshot_name)
|
||||||
|
execute(:delete_snapshot, {VmID: vm_id, SnapName: snapshot_name})
|
||||||
|
end
|
||||||
|
|
||||||
|
# Enable or disable VM integration services
|
||||||
|
#
|
||||||
|
# @param [Hash] config Integration services to enable or disable
|
||||||
|
# @return [nil]
|
||||||
|
# @note Keys in the config hash will be remapped if found in the
|
||||||
|
# INTEGRATION_SERVICES_MAP. If they are not, the name will
|
||||||
|
# be passed directly. This allows new integration services
|
||||||
|
# to configurable even if Vagrant is not aware of them.
|
||||||
def set_vm_integration_services(config)
|
def set_vm_integration_services(config)
|
||||||
execute("set_vm_integration_services.ps1", config)
|
config.each_pair do |srv_name, srv_enable|
|
||||||
|
args = {VMID: vm_id, Name: INTEGRATION_SERVICES_MAP.fetch(srv_name.to_sym, srv_name)}
|
||||||
|
args[:Name] = true if srv_enable
|
||||||
|
execute(:set_vm_integration_services, args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set the name of the VM
|
||||||
|
#
|
||||||
|
# @param [String] vmname Name of the VM
|
||||||
|
# @return [nil]
|
||||||
|
def set_name(vmname)
|
||||||
|
execute(:set_name, VMID: vm_id, VMName: vmname)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def execute_powershell(path, options, &block)
|
def execute_powershell(path, options, &block)
|
||||||
lib_path = Pathname.new(File.expand_path("../scripts", __FILE__))
|
lib_path = Pathname.new(File.expand_path("../scripts", __FILE__))
|
||||||
|
mod_path = lib_path.join("utils").to_s.gsub("/", "\\")
|
||||||
path = lib_path.join(path).to_s.gsub("/", "\\")
|
path = lib_path.join(path).to_s.gsub("/", "\\")
|
||||||
options = options || {}
|
options = options || {}
|
||||||
ps_options = []
|
ps_options = []
|
||||||
options.each do |key, value|
|
options.each do |key, value|
|
||||||
|
next if value == false
|
||||||
ps_options << "-#{key}"
|
ps_options << "-#{key}"
|
||||||
|
# If the value is a TrueClass assume switch
|
||||||
|
next if value == true
|
||||||
ps_options << "'#{value}'"
|
ps_options << "'#{value}'"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Always have a stop error action for failures
|
# Always have a stop error action for failures
|
||||||
ps_options << "-ErrorAction" << "Stop"
|
ps_options << "-ErrorAction" << "Stop"
|
||||||
|
|
||||||
opts = { notify: [:stdout, :stderr, :stdin] }
|
# Include our module path so we can nicely load helper modules
|
||||||
|
opts = {
|
||||||
|
notify: [:stdout, :stderr, :stdin],
|
||||||
|
env: {"PSModulePath" => "$env:PSModulePath+';#{mod_path}'"}
|
||||||
|
}
|
||||||
Vagrant::Util::PowerShell.execute(path, *ps_options, **opts, &block)
|
Vagrant::Util::PowerShell.execute(path, *ps_options, **opts, &block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# Include the following modules
|
#Requires -Modules VagrantMessages
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
||||||
|
|
||||||
$check = $(-Not (-Not (Get-Command "Hyper-V\Get-VMSwitch" -errorAction SilentlyContinue)))
|
$check = $(-Not (-Not (Get-Command "Hyper-V\Get-VMSwitch" -ErrorAction SilentlyContinue)))
|
||||||
$result = @{
|
$result = @{
|
||||||
result = $check
|
result = $check
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$Source,
|
[string]$Source,
|
||||||
|
|
||||||
|
@ -6,4 +8,11 @@ Param(
|
||||||
[string]$Destination
|
[string]$Destination
|
||||||
)
|
)
|
||||||
|
|
||||||
Hyper-V\New-VHD -Path $Destination -ParentPath $Source -ErrorAction Stop
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
try {
|
||||||
|
Hyper-V\New-VHD -Path $Destination -ParentPath $Source
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to clone drive: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
#Requires -Modules VagrantVM, VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[Guid] $VMID,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[string] $SwitchID=$null,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[string] $Memory=$null,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[string] $MaxMemory=$null,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[string] $Processors=$null,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[string] $AutoStartAction=$null,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[string] $AutoStopAction=$null,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[switch] $VirtualizationExtensions,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[switch] $EnableCheckpoints
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
try {
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VMID
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to locate VM: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Processors) {
|
||||||
|
try {
|
||||||
|
Set-VagrantVMCPUS -VM $VM -CPUCount ($Processors -as [int])
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to configure CPUs: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Memory -or $MaxMemory) {
|
||||||
|
try {
|
||||||
|
Set-VagrantVMMemory -VM $VM -Memory $Memory -MaxMemory $MaxMemory
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to configure memory: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($AutoStartAction -or $AutoStopAction) {
|
||||||
|
try {
|
||||||
|
Set-VagrantVMAutoActions -VM $VM -AutoStartAction $AutoStartAction -AutoStopAction $AutoStopAction
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to configure automatic actions: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($VirtualizationExtensions) {
|
||||||
|
$virtex = $true
|
||||||
|
} else {
|
||||||
|
$virtex = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Set-VagrantVMVirtExtensions -VM $VM -Enabled $virtex
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to configure virtualization extensions: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if($SwitchID) {
|
||||||
|
try {
|
||||||
|
$SwitchName = Get-VagrantVMSwitch -NameOrID $SwitchID
|
||||||
|
Set-VagrantVMSwitch -VM $VM -SwitchName $SwitchName
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to configure network adapter: ${PSItem}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($EnableCheckpoints) {
|
||||||
|
$checkpoints = "Standard"
|
||||||
|
$CheckpointAction = "enable"
|
||||||
|
} else {
|
||||||
|
$checkpoints = "Disabled"
|
||||||
|
$CheckpointAction = "disable"
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Hyper-V\Set-VM -VM $VM -CheckpointType $checkpoints
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to ${CheckpointAction} checkpoints on VM: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
|
@ -1,8 +1,17 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId,
|
[string]$VmId,
|
||||||
[string]$SnapName
|
[string]$SnapName
|
||||||
)
|
)
|
||||||
|
|
||||||
$VM = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
Hyper-V\Checkpoint-VM $VM -SnapshotName $SnapName
|
|
||||||
|
try {
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VmId
|
||||||
|
Hyper-V\Checkpoint-VM $VM -SnapshotName $SnapName
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to create snapshot: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId,
|
[string]$VmId,
|
||||||
[string]$SnapName
|
[string]$SnapName
|
||||||
)
|
)
|
||||||
|
|
||||||
$VM = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
Hyper-V\Remove-VMSnapshot $VM -Name $SnapName
|
|
||||||
|
try {
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VmId
|
||||||
|
Hyper-V\Remove-VMSnapshot $VM -Name $SnapName
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to delete snapshot: ${PSItem}"
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId
|
[string]$VmId
|
||||||
)
|
)
|
||||||
|
|
||||||
$VM = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
Hyper-V\Remove-VM $VM -Force
|
|
||||||
|
try {
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VmId
|
||||||
|
Hyper-V\Remove-VM $VM -Force
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to delete VM: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,29 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId,
|
[string]$VmId,
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$Path
|
[string]$Path
|
||||||
)
|
)
|
||||||
|
|
||||||
$vm = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
$vm | Hyper-V\Export-VM -Path $Path
|
|
||||||
|
try {
|
||||||
|
$vm = Hyper-V\Get-VM -Id $VmId
|
||||||
|
$vm | Hyper-V\Export-VM -Path $Path
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to export VM: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
# Prepare directory structure for box import
|
# Prepare directory structure for box import
|
||||||
$name = $vm.Name
|
try {
|
||||||
Move-Item $Path/$name/* $Path
|
$name = $vm.Name
|
||||||
Remove-Item -Path $Path/Snapshots -Force -Recurse
|
Move-Item $Path/$name/* $Path
|
||||||
Remove-Item -Path $Path/$name -Force
|
Remove-Item -Path $Path/Snapshots -Force -Recurse
|
||||||
|
Remove-Item -Path $Path/$name -Force
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to format exported box: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
|
#Requires -Modules VagrantMessages
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||||
# All Rights Reserved. Licensed under the MIT License.
|
# All Rights Reserved. Licensed under the MIT License.
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
|
|
||||||
param (
|
param (
|
||||||
[string]$vm_id = $(throw "-vm_id is required."),
|
[parameter (Mandatory=$true)]
|
||||||
[string]$guest_ip = $(throw "-guest_ip is required."),
|
[string]$vm_id,
|
||||||
[string]$username = $(throw "-guest_username is required."),
|
[parameter (Mandatory=$true)]
|
||||||
[string]$password = $(throw "-guest_password is required."),
|
[string]$guest_ip,
|
||||||
[string]$host_path = $(throw "-host_path is required."),
|
[parameter (Mandatory=$true)]
|
||||||
[string]$guest_path = $(throw "-guest_path is required.")
|
[string]$username,
|
||||||
)
|
[parameter (Mandatory=$true)]
|
||||||
|
[string]$password,
|
||||||
# Include the following modules
|
[parameter (Mandatory=$true)]
|
||||||
$presentDir = Split-Path -parent $PSCommandPath
|
[string]$host_path,
|
||||||
$modules = @()
|
[parameter (Mandatory=$true)]
|
||||||
$modules += $presentDir + "\utils\write_messages.ps1"
|
[string]$guest_path
|
||||||
forEach ($module in $modules) { . $module }
|
)
|
||||||
|
|
||||||
function Get-file-hash($source_path, $delimiter) {
|
function Get-file-hash($source_path, $delimiter) {
|
||||||
$source_files = @()
|
$source_files = @()
|
||||||
|
@ -120,4 +121,3 @@ $resultHash = @{
|
||||||
}
|
}
|
||||||
$result = ConvertTo-Json $resultHash
|
$result = ConvertTo-Json $resultHash
|
||||||
Write-Output-Message $result
|
Write-Output-Message $result
|
||||||
|
|
||||||
|
|
|
@ -1,56 +1,68 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId
|
[string]$VmId
|
||||||
)
|
)
|
||||||
|
|
||||||
# Include the following modules
|
$ErrorActionPreference = "Stop"
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
||||||
|
|
||||||
$vm = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
try {
|
||||||
$networks = Hyper-V\Get-VMNetworkAdapter -VM $vm
|
$vm = Hyper-V\Get-VM -Id $VmId
|
||||||
foreach ($network in $networks) {
|
} catch {
|
||||||
if ($network.IpAddresses.Length -gt 0) {
|
Write-Error-Message "Failed to locate VM: ${PSItem}"
|
||||||
foreach ($ip_address in $network.IpAddresses) {
|
exit 1
|
||||||
if ($ip_address.Contains(".") -And [string]::IsNullOrEmpty($ip4_address)) {
|
}
|
||||||
$ip4_address = $ip_address
|
|
||||||
} elseif ($ip_address.Contains(":") -And [string]::IsNullOrEmpty($ip6_address)) {
|
try {
|
||||||
$ip6_address = $ip_address
|
$networks = Hyper-V\Get-VMNetworkAdapter -VM $vm
|
||||||
|
foreach ($network in $networks) {
|
||||||
|
if ($network.IpAddresses.Length -gt 0) {
|
||||||
|
foreach ($ip_address in $network.IpAddresses) {
|
||||||
|
if ($ip_address.Contains(".") -And [string]::IsNullOrEmpty($ip4_address)) {
|
||||||
|
$ip4_address = $ip_address
|
||||||
|
} elseif ($ip_address.Contains(":") -And [string]::IsNullOrEmpty($ip6_address)) {
|
||||||
|
$ip6_address = $ip_address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# If no address was found in the network settings, check for
|
# If no address was found in the network settings, check for
|
||||||
# neighbor with mac address and see if an IP exists
|
# neighbor with mac address and see if an IP exists
|
||||||
if (([string]::IsNullOrEmpty($ip4_address)) -And ([string]::IsNullOrEmpty($ip6_address))) {
|
if (([string]::IsNullOrEmpty($ip4_address)) -And ([string]::IsNullOrEmpty($ip6_address))) {
|
||||||
$macaddresses = $vm | select -ExpandProperty NetworkAdapters | select MacAddress
|
$macaddresses = $vm | select -ExpandProperty NetworkAdapters | select MacAddress
|
||||||
foreach ($macaddr in $macaddresses) {
|
foreach ($macaddr in $macaddresses) {
|
||||||
$macaddress = $macaddr.MacAddress -replace '(.{2})(?!$)', '${1}-'
|
$macaddress = $macaddr.MacAddress -replace '(.{2})(?!$)', '${1}-'
|
||||||
$addr = Get-NetNeighbor -LinkLayerAddress $macaddress -ErrorAction SilentlyContinue | select IPAddress
|
$addr = Get-NetNeighbor -LinkLayerAddress $macaddress -ErrorAction SilentlyContinue | select IPAddress
|
||||||
if ($ip_address) {
|
if ($ip_address) {
|
||||||
$ip_address = $addr.IPAddress
|
$ip_address = $addr.IPAddress
|
||||||
if ($ip_address.Contains(".")) {
|
if ($ip_address.Contains(".")) {
|
||||||
$ip4_address = $ip_address
|
$ip4_address = $ip_address
|
||||||
} elseif ($ip_address.Contains(":")) {
|
} elseif ($ip_address.Contains(":")) {
|
||||||
$ip6_address = $ip_address
|
$ip6_address = $ip_address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (-Not ([string]::IsNullOrEmpty($ip4_address))) {
|
if (-Not ([string]::IsNullOrEmpty($ip4_address))) {
|
||||||
$guest_ipaddress = $ip4_address
|
$guest_ipaddress = $ip4_address
|
||||||
} elseif (-Not ([string]::IsNullOrEmpty($ip6_address))) {
|
} elseif (-Not ([string]::IsNullOrEmpty($ip6_address))) {
|
||||||
$guest_ipaddress = $ip6_address
|
$guest_ipaddress = $ip6_address
|
||||||
}
|
|
||||||
|
|
||||||
if (-Not ([string]::IsNullOrEmpty($guest_ipaddress))) {
|
|
||||||
$resultHash = @{
|
|
||||||
ip = $guest_ipaddress
|
|
||||||
}
|
}
|
||||||
$result = ConvertTo-Json $resultHash
|
|
||||||
Write-Output-Message $result
|
if (-Not ([string]::IsNullOrEmpty($guest_ipaddress))) {
|
||||||
} else {
|
$resultHash = @{
|
||||||
Write-Error-Message "Failed to determine IP address"
|
ip = $guest_ipaddress
|
||||||
|
}
|
||||||
|
$result = ConvertTo-Json $resultHash
|
||||||
|
Write-Output-Message $result
|
||||||
|
} else {
|
||||||
|
Write-Error-Message "Failed to determine IP address"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Unexpected error while detecting network configuration: ${PSItem}"
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,32 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId
|
[string]$VmId
|
||||||
)
|
)
|
||||||
|
|
||||||
# Include the following modules
|
$ErrorActionPreference = "Stop"
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
||||||
|
|
||||||
$ip_address = ""
|
try {
|
||||||
$vm = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
$ip_address = ""
|
||||||
$networks = Hyper-V\Get-VMNetworkAdapter -VM $vm
|
$vm = Hyper-V\Get-VM -Id $VmId
|
||||||
foreach ($network in $networks) {
|
$networks = Hyper-V\Get-VMNetworkAdapter -VM $vm
|
||||||
if ($network.MacAddress -gt 0) {
|
foreach ($network in $networks) {
|
||||||
$mac_address = $network.MacAddress
|
if ($network.MacAddress -gt 0) {
|
||||||
if (-Not ([string]::IsNullOrEmpty($mac_address))) {
|
$mac_address = $network.MacAddress
|
||||||
# We found our mac address!
|
if (-Not ([string]::IsNullOrEmpty($mac_address))) {
|
||||||
break
|
# We found our mac address!
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$resultHash = @{
|
||||||
$resultHash = @{
|
mac = "$mac_address"
|
||||||
mac = "$mac_address"
|
}
|
||||||
|
$result = ConvertTo-Json $resultHash
|
||||||
|
Write-Output-Message $result
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Unexpected error while fetching MAC: ${PSItem}"
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
$result = ConvertTo-Json $resultHash
|
|
||||||
Write-Output-Message $result
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
#Requires -Modules VagrantMessages
|
||||||
# This will have a SwitchType property. As far as I know the values are:
|
# This will have a SwitchType property. As far as I know the values are:
|
||||||
#
|
#
|
||||||
# 0 - Private
|
# 0 - Private
|
||||||
# 1 - Internal
|
# 1 - Internal
|
||||||
#
|
#
|
||||||
# Include the following modules
|
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
||||||
|
|
||||||
$Switches = @(Hyper-V\Get-VMSwitch `
|
$Switches = @(Hyper-V\Get-VMSwitch `
|
||||||
| Select-Object Name,SwitchType,NetAdapterInterfaceDescription,Id)
|
| Select-Object Name,SwitchType,NetAdapterInterfaceDescription,Id)
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId
|
[string]$VmId
|
||||||
)
|
)
|
||||||
|
|
||||||
# Include the following modules
|
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
||||||
|
|
||||||
# Make sure the exception type is loaded
|
# Make sure the exception type is loaded
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -37,7 +35,7 @@ try {
|
||||||
$State = "not_created"
|
$State = "not_created"
|
||||||
$Status = $State
|
$Status = $State
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# Include the following modules
|
#Requires -Modules VagrantMessages
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
||||||
|
|
||||||
# Windows version 10 and up have support for binary format
|
# Windows version 10 and up have support for binary format
|
||||||
$check = [System.Environment]::OSVersion.Version.Major -ge 10
|
$check = [System.Environment]::OSVersion.Version.Major -ge 10
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
#Requires -Modules VagrantVM, VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $VMConfigFile,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $DestinationPath,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $DataPath,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $SourcePath,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[switch] $LinkedClone,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[string] $VMName=$null
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
try {
|
||||||
|
if($LinkedClone) {
|
||||||
|
$linked = $true
|
||||||
|
} else {
|
||||||
|
$linked = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
$VM = New-VagrantVM -VMConfigFile $VMConfigFile -DestinationPath $DestinationPath `
|
||||||
|
-DataPath $DataPath -SourcePath $SourcePath -LinkedClone $linked -VMName $VMName
|
||||||
|
|
||||||
|
$Result = @{
|
||||||
|
id = $VM.Id.Guid;
|
||||||
|
}
|
||||||
|
Write-Output-Message (ConvertTo-Json $Result)
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
|
@ -1,165 +0,0 @@
|
||||||
Param(
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$vm_config_file,
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$source_path,
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$dest_path,
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$data_path,
|
|
||||||
|
|
||||||
[string]$switchid=$null,
|
|
||||||
[string]$memory=$null,
|
|
||||||
[string]$maxmemory=$null,
|
|
||||||
[string]$cpus=$null,
|
|
||||||
[string]$vmname=$null,
|
|
||||||
[string]$auto_start_action=$null,
|
|
||||||
[string]$auto_stop_action=$null,
|
|
||||||
[string]$differencing_disk=$null,
|
|
||||||
[string]$enable_virtualization_extensions=$False
|
|
||||||
)
|
|
||||||
|
|
||||||
# Include the following modules
|
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
||||||
|
|
||||||
$VmProperties = @{
|
|
||||||
Path = $vm_config_file
|
|
||||||
SnapshotFilePath = Join-Path $data_path 'Snapshots'
|
|
||||||
VhdDestinationPath = Join-Path $data_path 'Virtual Hard Disks'
|
|
||||||
VirtualMachinePath = $data_path
|
|
||||||
}
|
|
||||||
|
|
||||||
$vmConfig = (Hyper-V\Compare-VM -Copy -GenerateNewID @VmProperties)
|
|
||||||
|
|
||||||
$generation = $vmConfig.VM.Generation
|
|
||||||
|
|
||||||
if (!$vmname) {
|
|
||||||
# Get the name of the vm
|
|
||||||
$vm_name = $vmconfig.VM.VMName
|
|
||||||
} else {
|
|
||||||
$vm_name = $vmname
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$cpus) {
|
|
||||||
# Get the processorcount of the VM
|
|
||||||
$processors = (Hyper-V\Get-VMProcessor -VM $vmConfig.VM).Count
|
|
||||||
}else {
|
|
||||||
$processors = $cpus
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetUniqueName($name) {
|
|
||||||
Hyper-V\Get-VM | ForEach-Object -Process {
|
|
||||||
if ($name -eq $_.Name) {
|
|
||||||
$name = $name + "_1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $name
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
$name = $vm_name
|
|
||||||
$vm_name = GetUniqueName $name
|
|
||||||
} while ($vm_name -ne $name)
|
|
||||||
|
|
||||||
if (!$memory) {
|
|
||||||
$configMemory = Hyper-V\Get-VMMemory -VM $vmConfig.VM
|
|
||||||
$dynamicmemory = $configMemory.DynamicMemoryEnabled
|
|
||||||
|
|
||||||
$MemoryMaximumBytes = ($configMemory.Maximum)
|
|
||||||
$MemoryStartupBytes = ($configMemory.Startup)
|
|
||||||
$MemoryMinimumBytes = ($configMemory.Minimum)
|
|
||||||
} else {
|
|
||||||
if (!$maxmemory){
|
|
||||||
$dynamicmemory = $False
|
|
||||||
$MemoryMaximumBytes = ($memory -as [int]) * 1MB
|
|
||||||
$MemoryStartupBytes = ($memory -as [int]) * 1MB
|
|
||||||
$MemoryMinimumBytes = ($memory -as [int]) * 1MB
|
|
||||||
} else {
|
|
||||||
$dynamicmemory = $True
|
|
||||||
$MemoryMaximumBytes = ($maxmemory -as [int]) * 1MB
|
|
||||||
$MemoryStartupBytes = ($memory -as [int]) * 1MB
|
|
||||||
$MemoryMinimumBytes = ($memory -as [int]) * 1MB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$switchid) {
|
|
||||||
$switchname = (Hyper-V\Get-VMNetworkAdapter -VM $vmConfig.VM).SwitchName
|
|
||||||
} else {
|
|
||||||
$switchname = $(Hyper-V\Get-VMSwitch -Id $switchid).Name
|
|
||||||
}
|
|
||||||
|
|
||||||
# Enable nested virtualization if configured
|
|
||||||
if ($enable_virtualization_extensions -eq "True") {
|
|
||||||
Hyper-V\Set-VMProcessor -VM $vmConfig.VM -ExposeVirtualizationExtensions $true
|
|
||||||
}
|
|
||||||
|
|
||||||
$vmNetworkAdapter = Hyper-V\Get-VMNetworkAdapter -VM $vmConfig.VM
|
|
||||||
Hyper-V\Connect-VMNetworkAdapter -VMNetworkAdapter $vmNetworkAdapter -SwitchName $switchname
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -NewVMName $vm_name
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -ErrorAction "Stop"
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -ProcessorCount $processors
|
|
||||||
|
|
||||||
if ($dynamicmemory) {
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -DynamicMemory
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -MemoryMinimumBytes $MemoryMinimumBytes -MemoryMaximumBytes $MemoryMaximumBytes -MemoryStartupBytes $MemoryStartupBytes
|
|
||||||
} else {
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -StaticMemory
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -MemoryStartupBytes $MemoryStartupBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($notes) {
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -Notes $notes
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($auto_start_action) {
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -AutomaticStartAction $auto_start_action
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($auto_stop_action) {
|
|
||||||
Hyper-V\Set-VM -VM $vmConfig.VM -AutomaticStopAction $auto_stop_action
|
|
||||||
}
|
|
||||||
|
|
||||||
# Only set EFI secure boot for Gen 2 machines, not gen 1
|
|
||||||
if ($generation -ne 1) {
|
|
||||||
Hyper-V\Set-VMFirmware -VM $vmConfig.VM -EnableSecureBoot (Hyper-V\Get-VMFirmware -VM $vmConfig.VM).SecureBoot
|
|
||||||
}
|
|
||||||
|
|
||||||
$report = Hyper-V\Compare-VM -CompatibilityReport $vmConfig
|
|
||||||
|
|
||||||
# Stop if there are incompatibilities
|
|
||||||
if($report.Incompatibilities.Length -gt 0){
|
|
||||||
Write-Error-Message $(ConvertTo-Json $($report.Incompatibilities | Select -ExpandProperty Message))
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if($differencing_disk){
|
|
||||||
# Get all controller on the VM, first scsi, then IDE if it is a Gen 1 device
|
|
||||||
$controllers = Hyper-V\Get-VMScsiController -VM $vmConfig.VM
|
|
||||||
if($generation -eq 1){
|
|
||||||
$controllers = @($controllers) + @(Hyper-V\Get-VMIdeController -VM $vmConfig.VM)
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($controller in $controllers){
|
|
||||||
foreach($drive in $controller.Drives){
|
|
||||||
if([System.IO.Path]::GetFileName($drive.Path) -eq [System.IO.Path]::GetFileName($source_path)){
|
|
||||||
# Remove the old disk and replace it with a differencing version
|
|
||||||
$path = $drive.Path
|
|
||||||
Hyper-V\Remove-VMHardDiskDrive $drive
|
|
||||||
Hyper-V\New-VHD -Path $dest_path -ParentPath $source_path -ErrorAction Stop
|
|
||||||
Hyper-V\Add-VMHardDiskDrive -VM $vmConfig.VM -Path $dest_path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Hyper-V\Import-VM -CompatibilityReport $vmConfig
|
|
||||||
|
|
||||||
$vm_id = (Hyper-V\Get-VM $vm_name).id.guid
|
|
||||||
$resultHash = @{
|
|
||||||
name = $vm_name
|
|
||||||
id = $vm_id
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = ConvertTo-Json $resultHash
|
|
||||||
Write-Output-Message $result
|
|
|
@ -1,221 +0,0 @@
|
||||||
Param(
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$vm_config_file,
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$dest_path,
|
|
||||||
|
|
||||||
[string]$switchname=$null,
|
|
||||||
[string]$memory=$null,
|
|
||||||
[string]$maxmemory=$null,
|
|
||||||
[string]$cpus=$null,
|
|
||||||
[string]$vmname=$null,
|
|
||||||
[string]$auto_start_action=$null,
|
|
||||||
[string]$auto_stop_action=$null,
|
|
||||||
[string]$enable_virtualization_extensions=$False
|
|
||||||
)
|
|
||||||
|
|
||||||
# Include the following modules
|
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
||||||
|
|
||||||
[xml]$vmconfig = Get-Content -Path $vm_config_file
|
|
||||||
|
|
||||||
$generation = [int]($vmconfig.configuration.properties.subtype.'#text')+1
|
|
||||||
|
|
||||||
if (!$vmname) {
|
|
||||||
# Get the name of the vm
|
|
||||||
$vm_name = $vmconfig.configuration.properties.name.'#text'
|
|
||||||
}else {
|
|
||||||
$vm_name = $vmname
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$cpus) {
|
|
||||||
# Get the name of the vm
|
|
||||||
$processors = $vmconfig.configuration.settings.processors.count.'#text'
|
|
||||||
}else {
|
|
||||||
$processors = $cpus
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetUniqueName($name) {
|
|
||||||
Hyper-V\Get-VM | ForEach-Object -Process {
|
|
||||||
if ($name -eq $_.Name) {
|
|
||||||
$name = $name + "_1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $name
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
$name = $vm_name
|
|
||||||
$vm_name = GetUniqueName $name
|
|
||||||
} while ($vm_name -ne $name)
|
|
||||||
|
|
||||||
if (!$memory) {
|
|
||||||
$xmlmemory = (Select-Xml -xml $vmconfig -XPath "//memory").node.Bank
|
|
||||||
if ($xmlmemory.dynamic_memory_enabled."#text" -eq "True") {
|
|
||||||
$dynamicmemory = $True
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$dynamicmemory = $False
|
|
||||||
}
|
|
||||||
# Memory values need to be in bytes
|
|
||||||
$MemoryMaximumBytes = ($xmlmemory.limit."#text" -as [int]) * 1MB
|
|
||||||
$MemoryStartupBytes = ($xmlmemory.size."#text" -as [int]) * 1MB
|
|
||||||
$MemoryMinimumBytes = ($xmlmemory.reservation."#text" -as [int]) * 1MB
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!$maxmemory){
|
|
||||||
$dynamicmemory = $False
|
|
||||||
$MemoryMaximumBytes = ($memory -as [int]) * 1MB
|
|
||||||
$MemoryStartupBytes = ($memory -as [int]) * 1MB
|
|
||||||
$MemoryMinimumBytes = ($memory -as [int]) * 1MB
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$dynamicmemory = $True
|
|
||||||
$MemoryMaximumBytes = ($maxmemory -as [int]) * 1MB
|
|
||||||
$MemoryStartupBytes = ($memory -as [int]) * 1MB
|
|
||||||
$MemoryMinimumBytes = ($memory -as [int]) * 1MB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!$switchname) {
|
|
||||||
# Get the name of the virtual switch
|
|
||||||
$switchname = (Select-Xml -xml $vmconfig -XPath "//AltSwitchName").node."#text"
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($generation -eq 1) {
|
|
||||||
# Determine boot device
|
|
||||||
Switch ((Select-Xml -xml $vmconfig -XPath "//boot").node.device0."#text") {
|
|
||||||
"Floppy" { $bootdevice = "Floppy" }
|
|
||||||
"HardDrive" { $bootdevice = "IDE" }
|
|
||||||
"Optical" { $bootdevice = "CD" }
|
|
||||||
"Network" { $bootdevice = "LegacyNetworkAdapter" }
|
|
||||||
"Default" { $bootdevice = "IDE" }
|
|
||||||
} #switch
|
|
||||||
} else {
|
|
||||||
# Determine boot device
|
|
||||||
Switch ((Select-Xml -xml $vmconfig -XPath "//boot").node.device0."#text") {
|
|
||||||
"HardDrive" { $bootdevice = "VHD" }
|
|
||||||
"Optical" { $bootdevice = "CD" }
|
|
||||||
"Network" { $bootdevice = "NetworkAdapter" }
|
|
||||||
"Default" { $bootdevice = "VHD" }
|
|
||||||
} #switch
|
|
||||||
}
|
|
||||||
|
|
||||||
# Determine secure boot options
|
|
||||||
$secure_boot_enabled = (Select-Xml -xml $vmconfig -XPath "//secure_boot_enabled").Node."#text"
|
|
||||||
|
|
||||||
# Define a hash map of parameter values for New-VM
|
|
||||||
|
|
||||||
$vm_params = @{
|
|
||||||
Name = $vm_name
|
|
||||||
NoVHD = $True
|
|
||||||
MemoryStartupBytes = $MemoryStartupBytes
|
|
||||||
SwitchName = $switchname
|
|
||||||
BootDevice = $bootdevice
|
|
||||||
ErrorAction = "Stop"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Generation parameter was added in ps v4
|
|
||||||
if((get-command Hyper-V\New-VM).Parameters.Keys.Contains("generation")) {
|
|
||||||
$vm_params.Generation = $generation
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create the VM using the values in the hash map
|
|
||||||
|
|
||||||
$vm = Hyper-V\New-VM @vm_params
|
|
||||||
|
|
||||||
$notes = (Select-Xml -xml $vmconfig -XPath "//notes").node.'#text'
|
|
||||||
|
|
||||||
# Set-VM parameters to configure new VM with old values
|
|
||||||
|
|
||||||
$more_vm_params = @{
|
|
||||||
ProcessorCount = $processors
|
|
||||||
MemoryStartupBytes = $MemoryStartupBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
If ($dynamicmemory) {
|
|
||||||
$more_vm_params.Add("DynamicMemory",$True)
|
|
||||||
$more_vm_params.Add("MemoryMinimumBytes",$MemoryMinimumBytes)
|
|
||||||
$more_vm_params.Add("MemoryMaximumBytes", $MemoryMaximumBytes)
|
|
||||||
} else {
|
|
||||||
$more_vm_params.Add("StaticMemory",$True)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($notes) {
|
|
||||||
$more_vm_params.Add("Notes",$notes)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($auto_start_action) {
|
|
||||||
$more_vm_params.Add("AutomaticStartAction",$auto_start_action)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($auto_stop_action) {
|
|
||||||
$more_vm_params.Add("AutomaticStopAction",$auto_stop_action)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set the values on the VM
|
|
||||||
$vm | Hyper-V\Set-VM @more_vm_params -Passthru
|
|
||||||
|
|
||||||
# Add drives to the virtual machine
|
|
||||||
$controllers = Select-Xml -xml $vmconfig -xpath "//*[starts-with(name(.),'controller')]"
|
|
||||||
|
|
||||||
# Only set EFI secure boot for Gen 2 machines, not gen 1
|
|
||||||
if ($generation -ne 1) {
|
|
||||||
# Set EFI secure boot
|
|
||||||
if ($secure_boot_enabled -eq "True") {
|
|
||||||
Hyper-V\Set-VMFirmware -VM $vm -EnableSecureBoot On
|
|
||||||
} else {
|
|
||||||
Hyper-V\Set-VMFirmware -VM $vm -EnableSecureBoot Off
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Enable nested virtualization if configured
|
|
||||||
if ($enable_virtualization_extensions -eq "True") {
|
|
||||||
Hyper-V\Set-VMProcessor -VM $vm -ExposeVirtualizationExtensions $true
|
|
||||||
}
|
|
||||||
|
|
||||||
# A regular expression pattern to pull the number from controllers
|
|
||||||
[regex]$rx="\d"
|
|
||||||
|
|
||||||
foreach ($controller in $controllers) {
|
|
||||||
$node = $controller.Node
|
|
||||||
|
|
||||||
# Check for SCSI
|
|
||||||
if ($node.ParentNode.ChannelInstanceGuid) {
|
|
||||||
$ControllerType = "SCSI"
|
|
||||||
} else {
|
|
||||||
$ControllerType = "IDE"
|
|
||||||
}
|
|
||||||
|
|
||||||
$drives = $node.ChildNodes | where {$_.pathname."#text"}
|
|
||||||
foreach ($drive in $drives) {
|
|
||||||
#if drive type is ISO then set DVD Drive accordingly
|
|
||||||
$driveType = $drive.type."#text"
|
|
||||||
|
|
||||||
$addDriveParam = @{
|
|
||||||
ControllerNumber = $rx.Match($controller.node.name).value
|
|
||||||
Path = $dest_path
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($drive.pool_id."#text") {
|
|
||||||
$ResourcePoolName = $drive.pool_id."#text"
|
|
||||||
$addDriveParam.Add("ResourcePoolname",$ResourcePoolName)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($drivetype -eq 'VHD') {
|
|
||||||
$addDriveParam.add("ControllerType",$ControllerType)
|
|
||||||
$vm | Hyper-V\Add-VMHardDiskDrive @AddDriveparam
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$vm_id = (Hyper-V\Get-VM $vm_name).id.guid
|
|
||||||
$resultHash = @{
|
|
||||||
name = $vm_name
|
|
||||||
id = $vm_id
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = ConvertTo-Json $resultHash
|
|
||||||
Write-Output-Message $result
|
|
|
@ -1,12 +1,19 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId
|
[string]$VmId
|
||||||
)
|
)
|
||||||
|
|
||||||
$VM = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
$Snapshots = @(Hyper-V\Get-VMSnapshot $VM | Select-Object Name)
|
|
||||||
$result = ConvertTo-json $Snapshots
|
|
||||||
|
|
||||||
Write-Host "===Begin-Output==="
|
try {
|
||||||
Write-Host $result
|
$VM = Hyper-V\Get-VM -Id $VmId
|
||||||
Write-Host "===End-Output==="
|
$Snapshots = @(Hyper-V\Get-VMSnapshot $VM | Select-Object Name)
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to get snapshot list: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = ConvertTo-json $Snapshots
|
||||||
|
Write-Output-Message $result
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId,
|
[string]$VmId,
|
||||||
[string]$SnapName
|
[string]$SnapName
|
||||||
)
|
)
|
||||||
|
|
||||||
$VM = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
Hyper-V\Restore-VMSnapshot $VM -Name $SnapName -Confirm:$false
|
|
||||||
|
try {
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VmId
|
||||||
|
Hyper-V\Restore-VMSnapshot $VM -Name $SnapName -Confirm:$false
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to restore snapshot: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId
|
[string]$VmId
|
||||||
)
|
)
|
||||||
|
|
||||||
$VM = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
Hyper-V\Resume-VM $VM
|
|
||||||
|
try {
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VmId
|
||||||
|
Hyper-V\Resume-VM $VM
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to resume VM: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[Guid] $VMID,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $VMName
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
try {
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VMID
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to locate VM: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Hyper-V\Set-VM -VM $VM -NewVMName $VMName
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to assign new VM name ${VMName}: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
param (
|
#Requires -Modules VagrantMessages
|
||||||
[string]$VmId = $(throw "-VmId is required."),
|
|
||||||
[string]$Mac = $(throw "-Mac ")
|
|
||||||
)
|
|
||||||
|
|
||||||
# Include the following modules
|
param (
|
||||||
$presentDir = Split-Path -parent $PSCommandPath
|
[parameter (Mandatory=$true)]
|
||||||
$modules = @()
|
[string]$VmId,
|
||||||
$modules += $presentDir + "\utils\write_messages.ps1"
|
[parameter (Mandatory=$true)]
|
||||||
forEach ($module in $modules) { . $module }
|
[string]$Mac
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$vm = Hyper-V\Get-VM -Id $VmId -ErrorAction "stop"
|
$vm = Hyper-V\Get-VM -Id $VmId
|
||||||
Hyper-V\Set-VMNetworkAdapter $vm -StaticMacAddress $Mac -ErrorAction "stop"
|
Hyper-V\Set-VMNetworkAdapter $vm -StaticMacAddress $Mac
|
||||||
}
|
} catch {
|
||||||
catch {
|
Write-Error-Message "Failed to set VM MAC address: ${PSItem}"
|
||||||
Write-Error-Message "Failed to set VM's MAC address $_"
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
param (
|
param (
|
||||||
[string]$VmId = $(throw "-VmId is required."),
|
[parameter (Mandatory=$true)]
|
||||||
[int]$VlanId = $(throw "-VlanId ")
|
[string]$VmId,
|
||||||
)
|
[parameter (Mandatory=$true)]
|
||||||
|
[int]$VlanId
|
||||||
|
)
|
||||||
|
|
||||||
# Include the following modules
|
# Include the following modules
|
||||||
$presentDir = Split-Path -parent $PSCommandPath
|
$presentDir = Split-Path -parent $PSCommandPath
|
||||||
|
|
|
@ -1,37 +1,27 @@
|
||||||
|
#Requires -Modules VagrantVM, VagrantMessages
|
||||||
|
|
||||||
param (
|
param (
|
||||||
[string] $VmId,
|
[parameter (Mandatory=$true)]
|
||||||
[string] $guest_service_interface = $null,
|
[string] $VMID,
|
||||||
[string] $heartbeat = $null,
|
[parameter (Mandatory=$true)]
|
||||||
[string] $key_value_pair_exchange = $null,
|
[string] $Name,
|
||||||
[string] $shutdown = $null,
|
[parameter (Mandatory=$false)]
|
||||||
[string] $time_synchronization = $null,
|
[switch] $Enable
|
||||||
[string] $vss = $null
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Include the following modules
|
$ErrorActionPreference = "Stop"
|
||||||
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
|
||||||
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
|
||||||
|
|
||||||
$vm = Hyper-V\Get-VM -Id $VmId -ErrorAction "stop"
|
try {
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VMID
|
||||||
# Set the service based on value
|
} catch {
|
||||||
function VmSetService
|
Write-Error-Message "Failed to locate VM: ${PSItem}"
|
||||||
{
|
exit 1
|
||||||
param ([string] $Name, [string] $Value, [Microsoft.HyperV.PowerShell.VirtualMachine] $Vm)
|
|
||||||
|
|
||||||
if ($Value -ne $null){
|
|
||||||
if($Value -eq "true"){
|
|
||||||
Hyper-V\Enable-VMIntegrationService -VM $Vm -Name $Name
|
|
||||||
}
|
|
||||||
if($Value -eq "false"){
|
|
||||||
Hyper-V\Disable-VMIntegrationService -VM $Vm -Name $Name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VmSetService -Name "Guest Service Interface" -Value $guest_service_interface -Vm $vm
|
try {
|
||||||
VmSetService -Name "Heartbeat" -Value $heartbeat -Vm $vm
|
Set-VagrantVMService -VM $VM -Name $Name -Enable $enabled
|
||||||
VmSetService -Name "Key-Value Pair Exchange" -Value $key_value_pair_exchange -Vm $vm
|
} catch {
|
||||||
VmSetService -Name "Shutdown" -Value $shutdown -Vm $vm
|
if($enabled){ $action = "enable" } else { $action = "disable" }
|
||||||
VmSetService -Name "Time Synchronization" -Value $time_synchronization -Vm $vm
|
Write-Error-Message "Failed to ${action} VM integration service ${Name}: ${PSItem}"
|
||||||
VmSetService -Name "VSS" -Value $vss -Vm $vm
|
exit 1
|
||||||
|
}
|
||||||
|
|
|
@ -1,27 +1,26 @@
|
||||||
param (
|
#Requires -Modules VagrantMessages
|
||||||
[string]$VmId = $(throw "-VmId is required.")
|
|
||||||
)
|
|
||||||
|
|
||||||
# Include the following modules
|
param (
|
||||||
$presentDir = Split-Path -parent $PSCommandPath
|
[parameter (Mandatory=$true)]
|
||||||
$modules = @()
|
[string]$VmId
|
||||||
$modules += $presentDir + "\utils\write_messages.ps1"
|
)
|
||||||
forEach ($module in $modules) { . $module }
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$vm = Hyper-V\Get-VM -Id $VmId -ErrorAction "stop"
|
$vm = Hyper-V\Get-VM -Id $VmId
|
||||||
Hyper-V\Start-VM $vm -ErrorAction "stop"
|
Hyper-V\Start-VM $vm
|
||||||
$state = $vm.state
|
$state = $vm.state
|
||||||
$status = $vm.status
|
$status = $vm.status
|
||||||
$name = $vm.name
|
$name = $vm.name
|
||||||
$resultHash = @{
|
$resultHash = @{
|
||||||
state = "$state"
|
state = "$state"
|
||||||
status = "$status"
|
status = "$status"
|
||||||
name = "$name"
|
name = "$name"
|
||||||
}
|
}
|
||||||
$result = ConvertTo-Json $resultHash
|
$result = ConvertTo-Json $resultHash
|
||||||
Write-Output-Message $result
|
Write-Output-Message $result
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to start VM ${PSItem}"
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
catch {
|
|
||||||
Write-Error-Message "Failed to start a VM $_"
|
|
||||||
}
|
|
|
@ -1,8 +1,17 @@
|
||||||
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
Param(
|
Param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId
|
[string]$VmId
|
||||||
)
|
)
|
||||||
|
|
||||||
# Shuts down virtual machine regardless of any unsaved application data
|
$ErrorActionPreference = "Stop"
|
||||||
$VM = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
|
||||||
Hyper-V\Stop-VM $VM -Force
|
try{
|
||||||
|
# Shuts down virtual machine regardless of any unsaved application data
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VmId
|
||||||
|
Hyper-V\Stop-VM $VM -Force
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to stop VM: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
Param(
|
#Requires -Modules VagrantMessages
|
||||||
|
|
||||||
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$VmId
|
[string]$VmId
|
||||||
)
|
)
|
||||||
|
|
||||||
$VM = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
Hyper-V\Suspend-VM $VM
|
|
||||||
|
try{
|
||||||
|
$VM = Hyper-V\Get-VM -Id $VmId
|
||||||
|
Hyper-V\Suspend-VM $VM
|
||||||
|
} catch {
|
||||||
|
Write-Error-Message "Failed to suspend VM: ${PSItem}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||||
|
# All Rights Reserved. Licensed under the MIT License.
|
||||||
|
#--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function Write-Error-Message {
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true,Position=0)]
|
||||||
|
[string] $Message
|
||||||
|
)
|
||||||
|
$error_message = @{
|
||||||
|
error = $Message
|
||||||
|
}
|
||||||
|
Write-Host "===Begin-Error==="
|
||||||
|
Write-Host (ConvertTo-Json $error_message)
|
||||||
|
Write-Host "===End-Error==="
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-Output-Message {
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true,Position=0)]
|
||||||
|
[string] $Message
|
||||||
|
)
|
||||||
|
Write-Host "===Begin-Output==="
|
||||||
|
Write-Host $Message
|
||||||
|
Write-Host "===End-Output==="
|
||||||
|
}
|
|
@ -0,0 +1,616 @@
|
||||||
|
# Vagrant VM creation functions
|
||||||
|
|
||||||
|
function New-VagrantVM {
|
||||||
|
param (
|
||||||
|
[parameter(Mandatory=$true)]
|
||||||
|
[string] $VMConfigFile,
|
||||||
|
[parameter(Mandatory=$true)]
|
||||||
|
[string] $DestinationPath,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $DataPath,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $SourcePath,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[bool] $LinkedClone = $false,
|
||||||
|
[parameter(Mandatory=$false)]
|
||||||
|
[string] $VMName
|
||||||
|
)
|
||||||
|
if([IO.Path]::GetExtension($VMConfigFile).ToLower() -eq ".xml") {
|
||||||
|
return New-VagrantVMXML @PSBoundParameters
|
||||||
|
} else {
|
||||||
|
return New-VagrantVMVMCX @PSBoundParameters
|
||||||
|
}
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Create a new Vagrant Hyper-V VM by cloning original. This
|
||||||
|
is the general use function with will call the specialized
|
||||||
|
function based on the extension of the configuration file.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
Using an existing Hyper-V VM a new Hyper-V VM is created
|
||||||
|
by cloning the original.
|
||||||
|
|
||||||
|
.PARAMETER VMConfigFile
|
||||||
|
Path to the original Hyper-V VM configuration file.
|
||||||
|
|
||||||
|
.PARAMETER DestinationPath
|
||||||
|
Path to new Hyper-V VM hard drive.
|
||||||
|
|
||||||
|
.PARAMETER DataPath
|
||||||
|
Directory path of the original Hyper-V VM to be cloned.
|
||||||
|
|
||||||
|
.PARAMETER SourcePath
|
||||||
|
Path to the original Hyper-V VM hard drive.
|
||||||
|
|
||||||
|
.PARAMETER LinkedClone
|
||||||
|
New Hyper-V VM should be linked clone instead of complete copy.
|
||||||
|
|
||||||
|
.PARAMETER VMName
|
||||||
|
Name of the new Hyper-V VM.
|
||||||
|
|
||||||
|
.INPUTS
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
.OUTPUTS
|
||||||
|
|
||||||
|
VirtualMachine. The cloned Hyper-V VM.
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
function New-VagrantVMVMCX {
|
||||||
|
param (
|
||||||
|
[parameter(Mandatory=$true)]
|
||||||
|
[string] $VMConfigFile,
|
||||||
|
[parameter(Mandatory=$true)]
|
||||||
|
[string] $DestinationPath,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $DataPath,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $SourcePath,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[bool] $LinkedClone = $false,
|
||||||
|
[parameter(Mandatory=$false)]
|
||||||
|
[string] $VMName
|
||||||
|
)
|
||||||
|
|
||||||
|
$NewVMConfig = @{
|
||||||
|
Path = $VMConfigFile;
|
||||||
|
SnapshotFilePath = Join-Path $DataPath "Snapshots";
|
||||||
|
VhdDestinationPath = Join-Path $DataPath "Virtual Hard Disks";
|
||||||
|
VirtualMachinePath = $DataPath;
|
||||||
|
}
|
||||||
|
$VMConfig = (Hyper-V\Compare-VM -Copy -GenerateNewID @NewVMConfig)
|
||||||
|
$VM = $VMConfig.VM
|
||||||
|
$Gen = $VM.Generation
|
||||||
|
|
||||||
|
# Set VM name if name has been provided
|
||||||
|
if($VMName) {
|
||||||
|
Hyper-V\Set-VM -VM $VM -NewVMName $VMName
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set EFI secure boot on machines after Gen 1
|
||||||
|
if($Gen -gt 1) {
|
||||||
|
Hyper-V\Set-VMFirmware -VM $VM -EnableSecureBoot (Hyper-V\Get-VMFirmware -VM $VM).SecureBoot
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify new VM
|
||||||
|
$Report = Hyper-V\Compare-VM -CompatibilityReport $VMConfig
|
||||||
|
if($Report.Incompatibilities.Length -gt 0){
|
||||||
|
throw $(ConvertTo-Json $($Report.Incompatibilities | Select -ExpandProperty Message))
|
||||||
|
}
|
||||||
|
|
||||||
|
if($LinkedClone) {
|
||||||
|
$Controllers = Hyper-V\Get-VMScsiController -VM $VM
|
||||||
|
if($Gen -eq 1){
|
||||||
|
$Controllers = @($Controllers) + @(Hyper-V\Get-VMIdeController -VM $VM)
|
||||||
|
}
|
||||||
|
foreach($Controller in $Controllers) {
|
||||||
|
foreach($Drive in $Controller.Drives) {
|
||||||
|
if([System.IO.Path]::GetFileName($Drive.Path) -eq [System.IO.Path]::GetFileName($SourcePath)) {
|
||||||
|
$Path = $Drive.Path
|
||||||
|
Hyper-V\Remove-VMHardDiskDrive $Drive
|
||||||
|
Hyper-V\New-VHD -Path $DestinationPath -ParentPath $SourcePath
|
||||||
|
Hyper-V\AddVMHardDiskDrive -VM $VM -Path $DestinationPath
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return Hyper-V\Import-VM -CompatibilityReport $VMConfig
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Create a new Vagrant Hyper-V VM by cloning original (VMCX based).
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
Using an existing Hyper-V VM a new Hyper-V VM is created
|
||||||
|
by cloning the original.
|
||||||
|
|
||||||
|
.PARAMETER VMConfigFile
|
||||||
|
Path to the original Hyper-V VM configuration file.
|
||||||
|
|
||||||
|
.PARAMETER DestinationPath
|
||||||
|
Path to new Hyper-V VM hard drive.
|
||||||
|
|
||||||
|
.PARAMETER DataPath
|
||||||
|
Directory path of the original Hyper-V VM to be cloned.
|
||||||
|
|
||||||
|
.PARAMETER SourcePath
|
||||||
|
Path to the original Hyper-V VM hard drive.
|
||||||
|
|
||||||
|
.PARAMETER LinkedClone
|
||||||
|
New Hyper-V VM should be linked clone instead of complete copy.
|
||||||
|
|
||||||
|
.PARAMETER VMName
|
||||||
|
Name of the new Hyper-V VM.
|
||||||
|
|
||||||
|
.INPUTS
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
.OUTPUTS
|
||||||
|
|
||||||
|
VirtualMachine. The cloned Hyper-V VM.
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
function New-VagrantVMXML {
|
||||||
|
param (
|
||||||
|
[parameter(Mandatory=$true)]
|
||||||
|
[string] $VMConfigFile,
|
||||||
|
[parameter(Mandatory=$true)]
|
||||||
|
[string] $DestinationPath,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $DataPath,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $SourcePath,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[bool] $LinkedClone = $false,
|
||||||
|
[parameter(Mandatory=$false)]
|
||||||
|
[string] $VMName
|
||||||
|
)
|
||||||
|
|
||||||
|
$DestinationDirectory = [System.IO.Path]::GetDirectoryName($DestinationPath)
|
||||||
|
New-Item -ItemType Directory -Force -Path $DestinationDirectory
|
||||||
|
|
||||||
|
if($LinkedClone){
|
||||||
|
Hyper-V\New-VHD -Path $DestinationPath -ParentPath $SourcePath -ErrorAction Stop
|
||||||
|
} else {
|
||||||
|
Copy-Item $SourcePath -Destination $DestinationPath -ErrorAction Stop
|
||||||
|
}
|
||||||
|
|
||||||
|
[xml]$VMConfig = Get-Content -Path $VMConfigFile
|
||||||
|
$Gen = [int]($VMConfig.configuration.properties.subtype."#text") + 1
|
||||||
|
if(!$VMName) {
|
||||||
|
$VMName = $VMConfig.configuration.properties.name."#text"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine boot device
|
||||||
|
if($Gen -eq 1) {
|
||||||
|
Switch ((Select-Xml -xml $VMConfig -XPath "//boot").node.device0."#text") {
|
||||||
|
"Floppy" { $BootDevice = "Floppy" }
|
||||||
|
"HardDrive" { $BootDevice = "IDE" }
|
||||||
|
"Optical" { $BootDevice = "CD" }
|
||||||
|
"Network" { $BootDevice = "LegacyNetworkAdapter" }
|
||||||
|
"Default" { $BootDevice = "IDE" }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Switch ((Select-Xml -xml $VMConfig -XPath "//boot").node.device0."#text") {
|
||||||
|
"HardDrive" { $BootDevice = "VHD" }
|
||||||
|
"Optical" { $BootDevice = "CD" }
|
||||||
|
"Network" { $BootDevice = "NetworkAdapter" }
|
||||||
|
"Default" { $BootDevice = "VHD" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine if secure boot is enabled
|
||||||
|
$SecureBoot = (Select-Xml -XML $VMConfig -XPath "//secure_boot_enabled").Node."#text"
|
||||||
|
|
||||||
|
$NewVMConfig = @{
|
||||||
|
Name = $VMName;
|
||||||
|
NoVHD = $true;
|
||||||
|
BootDevice = $BootDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generation parameter in PS4 so validate before using
|
||||||
|
if((Get-Command Hyper-V\New-VM).Parameters.Keys.Contains("generation")) {
|
||||||
|
$NewVMConfig.Generation = $Gen
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create new VM instance
|
||||||
|
$VM = Hyper-V\New-VM @NewVMConfig
|
||||||
|
|
||||||
|
# Configure secure boot
|
||||||
|
if($Gen -gt 1) {
|
||||||
|
if($SecureBoot -eq "True") {
|
||||||
|
Hyper-V\Set-VMFirmware -VM $VM -EnableSecureBoot On
|
||||||
|
} else {
|
||||||
|
Hyper-V\Set-VMFirmware -VM $VM -EnableSecureBoot Off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configure drives
|
||||||
|
[regex]$DriveNumberMatcher = "\d"
|
||||||
|
$Controllers = Select-Xml -XML $VMConfig -XPath "//*[starts-with(name(.),'controller')]"
|
||||||
|
|
||||||
|
foreach($Controller in $Controllers) {
|
||||||
|
$Node = $Controller.Node
|
||||||
|
if($Node.ParentNode.ChannelInstanceGuid) {
|
||||||
|
$ControllerType = "SCSI"
|
||||||
|
} else {
|
||||||
|
$ControllerType = "IDE"
|
||||||
|
}
|
||||||
|
$Drives = $Node.ChildNodes | where {$_.pathname."#text"}
|
||||||
|
foreach($Drive in $Drives) {
|
||||||
|
$DriveType = $Drive.type."#text"
|
||||||
|
if($DriveType -ne "VHD") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$NewDriveConfig = @{
|
||||||
|
ControllerNumber = $DriveNumberMatcher.Match($Controller.node.name).value;
|
||||||
|
Path = $DestinationPath;
|
||||||
|
ControllerType = $ControllerType;
|
||||||
|
}
|
||||||
|
if($Drive.pool_id."#text") {
|
||||||
|
$NewDriveConfig.ResourcePoolname = $Drive.pool_id."#text"
|
||||||
|
}
|
||||||
|
$VM | Hyper-V\Add-VMHardDiskDrive @NewDriveConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Apply original VM configuration to new VM instance
|
||||||
|
|
||||||
|
$processors = $VMConfig.configuration.settings.processors.count."#text"
|
||||||
|
$notes = (Select-Xml -XML $VMConfig -XPath "//notes").node."#text"
|
||||||
|
$memory = (Select-Xml -XML $VMConfig -XPath "//memory").node.Bank
|
||||||
|
if ($memory.dynamic_memory_enabled."#text" -eq "True") {
|
||||||
|
$dynamicmemory = $True
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$dynamicmemory = $False
|
||||||
|
}
|
||||||
|
# Memory values need to be in bytes
|
||||||
|
$MemoryMaximumBytes = ($memory.limit."#text" -as [int]) * 1MB
|
||||||
|
$MemoryStartupBytes = ($memory.size."#text" -as [int]) * 1MB
|
||||||
|
$MemoryMinimumBytes = ($memory.reservation."#text" -as [int]) * 1MB
|
||||||
|
|
||||||
|
$Config = @{
|
||||||
|
ProcessorCount = $processors;
|
||||||
|
MemoryStartupBytes = $MemoryStartupBytes
|
||||||
|
}
|
||||||
|
if($dynamicmemory) {
|
||||||
|
$Config.DynamicMemory = $true
|
||||||
|
$Config.MemoryMinimumBytes = $MemoryMinimumBytes
|
||||||
|
$Config.MemoryMaximumBytes = $MemoryMaximumBytes
|
||||||
|
} else {
|
||||||
|
$Config.StaticMemory = $true
|
||||||
|
}
|
||||||
|
if($notes) {
|
||||||
|
$Config.Notes = $notes
|
||||||
|
}
|
||||||
|
Hyper-V\Set-VM -VM $VM @Config
|
||||||
|
|
||||||
|
return $VM
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Create a new Vagrant Hyper-V VM by cloning original (XML based).
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
Using an existing Hyper-V VM a new Hyper-V VM is created
|
||||||
|
by cloning the original.
|
||||||
|
|
||||||
|
.PARAMETER VMConfigFile
|
||||||
|
Path to the original Hyper-V VM configuration file.
|
||||||
|
|
||||||
|
.PARAMETER DestinationPath
|
||||||
|
Path to new Hyper-V VM hard drive.
|
||||||
|
|
||||||
|
.PARAMETER DataPath
|
||||||
|
Directory path of the original Hyper-V VM to be cloned.
|
||||||
|
|
||||||
|
.PARAMETER SourcePath
|
||||||
|
Path to the original Hyper-V VM hard drive.
|
||||||
|
|
||||||
|
.PARAMETER LinkedClone
|
||||||
|
New Hyper-V VM should be linked clone instead of complete copy.
|
||||||
|
|
||||||
|
.PARAMETER VMName
|
||||||
|
Name of the new Hyper-V VM.
|
||||||
|
|
||||||
|
.INPUTS
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
.OUTPUTS
|
||||||
|
|
||||||
|
VirtualMachine. The cloned Hyper-V VM.
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
# Vagrant VM configuration functions
|
||||||
|
|
||||||
|
function Set-VagrantVMMemory {
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[Microsoft.HyperV.PowerShell.VirtualMachine] $VM,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[int] $Memory,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[int] $MaxMemory
|
||||||
|
)
|
||||||
|
|
||||||
|
$ConfigMemory = Hyper-V\Get-VMMemory -VM $VM
|
||||||
|
|
||||||
|
if(!$Memory) {
|
||||||
|
$MemoryStartupBytes = ($ConfigMemory.Startup)
|
||||||
|
$MemoryMinimumBytes = ($ConfigMemory.Minimum)
|
||||||
|
$MemoryMaximumBytes = ($ConfigMemory.Maximum)
|
||||||
|
} else {
|
||||||
|
$MemoryStartupBytes = $Memory * 1MB
|
||||||
|
$MemoryMinimumBytes = $Memory * 1MB
|
||||||
|
$MemoryMaximumBytes = $Memory * 1MB
|
||||||
|
}
|
||||||
|
|
||||||
|
if($MaxMemory) {
|
||||||
|
$DynamicMemory = $true
|
||||||
|
$MemoryMaximumBytes = $MaxMemory * 1MB
|
||||||
|
}
|
||||||
|
|
||||||
|
if($DynamicMemory) {
|
||||||
|
Hyper-V\Set-VM -VM $VM -DynamicMemory
|
||||||
|
Hyper-V\Set-VM -VM $VM -MemoryMinimumBytes $MemoryMinimumBytes -MemoryMaximumBytes `
|
||||||
|
$MemoryMaximumBytes -MemoryStartupBytes $MemoryStartupBytes
|
||||||
|
} else {
|
||||||
|
Hyper-V\Set-VM -VM $VM -StaticMemory
|
||||||
|
Hyper-V\Set-VM -VM $VM -MemoryStartupBytes $MemoryStartupBytes
|
||||||
|
}
|
||||||
|
return $VM
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Configure VM memory settings.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
Adjusts the VM memory settings. If MaxMemory is defined, dynamic memory
|
||||||
|
is enabled on the VM.
|
||||||
|
|
||||||
|
.PARAMETER VM
|
||||||
|
|
||||||
|
Hyper-V VM for modification.
|
||||||
|
|
||||||
|
.Parameter Memory
|
||||||
|
|
||||||
|
Memory to allocate to the given VM in MB.
|
||||||
|
|
||||||
|
.Parameter MaxMemory
|
||||||
|
|
||||||
|
Maximum memory to allocate to the given VM in MB. When this value is
|
||||||
|
provided dynamic memory is enabled for the VM. The Memory value or
|
||||||
|
the currently configured memory of the VM will be used as the minimum
|
||||||
|
and startup memory value.
|
||||||
|
|
||||||
|
.Output
|
||||||
|
|
||||||
|
VirtualMachine.
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
function Set-VagrantVMCPUS {
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[Microsoft.HyperV.PowerShell.VirtualMachine] $VM,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[int] $CPUCount
|
||||||
|
)
|
||||||
|
|
||||||
|
if($CPUCount) {
|
||||||
|
Hyper-V\Set-VM -VM $VM -ProcessorCount $CPUCount
|
||||||
|
}
|
||||||
|
return $VM
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Configure VM CPU count.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
Configure the number of CPUs on the given VM.
|
||||||
|
|
||||||
|
.PARAMETER VM
|
||||||
|
|
||||||
|
Hyper-V VM for modification.
|
||||||
|
|
||||||
|
.PARAMETER CPUCount
|
||||||
|
|
||||||
|
Number of CPUs.
|
||||||
|
|
||||||
|
.Output
|
||||||
|
|
||||||
|
VirtualMachine.
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
function Set-VagrantVMVirtExtensions {
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[Microsoft.HyperV.PowerShell.VirtualMachine] $VM,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[bool] $Enabled=$false
|
||||||
|
)
|
||||||
|
|
||||||
|
Hyper-V\Set-VMProcessor -VM $VM -ExposeVirtualizationExtensions $Enabled
|
||||||
|
return $VM
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Enable virtualization extensions on VM.
|
||||||
|
|
||||||
|
.PARAMETER VM
|
||||||
|
|
||||||
|
Hyper-V VM for modification.
|
||||||
|
|
||||||
|
.PARAMETER Enabled
|
||||||
|
|
||||||
|
Enable virtualization extensions on given VM.
|
||||||
|
|
||||||
|
.OUTPUT
|
||||||
|
|
||||||
|
VirtualMachine.
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
function Set-VagrantVMAutoActions {
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[Microsoft.HyperV.PowerShell.VirtualMachine] $VM,
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[string] $AutoStartAction="Nothing",
|
||||||
|
[parameter (Mandatory=$false)]
|
||||||
|
[string] $AutoStopAction="ShutDown"
|
||||||
|
)
|
||||||
|
|
||||||
|
Hyper-V\Set-VM -VM $VM -AutomaticStartAction $AutoStartAction
|
||||||
|
Hyper-V\Set-VM -VM $VM -AutomaticStopAction $AutoStopAction
|
||||||
|
return $VM
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Configure automatic start and stop actions for VM
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
Configures the automatic start and automatic stop actions for
|
||||||
|
the given VM.
|
||||||
|
|
||||||
|
.PARAMETER VM
|
||||||
|
|
||||||
|
Hyper-V VM for modification.
|
||||||
|
|
||||||
|
.PARAMETER AutoStartAction
|
||||||
|
|
||||||
|
Action the VM should automatically take when the host is started.
|
||||||
|
|
||||||
|
.PARAMETER AutoStopAction
|
||||||
|
|
||||||
|
Action the VM should automatically take when the host is stopped.
|
||||||
|
|
||||||
|
.OUTPUT
|
||||||
|
|
||||||
|
VirtualMachine.
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
function Set-VagrantVMService {
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[Microsoft.HyperV.PowerShell.VirtualMachine] $VM,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $Name,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[bool] $Enable
|
||||||
|
)
|
||||||
|
|
||||||
|
if($Enable) {
|
||||||
|
Hyper-V\Enable-VMIntegrationService -VM $VM -Name $Name
|
||||||
|
} else {
|
||||||
|
Hyper-V\Disable-VMIntegrationService -VM $VM -Name $Name
|
||||||
|
}
|
||||||
|
return $VM
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Enable or disable Hyper-V VM integration services.
|
||||||
|
|
||||||
|
.PARAMETER VM
|
||||||
|
|
||||||
|
Hyper-V VM for modification.
|
||||||
|
|
||||||
|
.PARAMETER Name
|
||||||
|
|
||||||
|
Name of the integration service.
|
||||||
|
|
||||||
|
.PARAMETER Enable
|
||||||
|
|
||||||
|
Enable or disable the service.
|
||||||
|
|
||||||
|
.OUTPUT
|
||||||
|
|
||||||
|
VirtualMachine.
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
# Vagrant networking functions
|
||||||
|
|
||||||
|
function Get-VagrantVMSwitch {
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[string] $NameOrID
|
||||||
|
)
|
||||||
|
$SwitchName = $(Hyper-V\Get-VMSwitch -Id $NameOrID).Name
|
||||||
|
if(!$SwitchName) {
|
||||||
|
$SwitchName = $(Hyper-V\Get-VMSwitch -Name $NameOrID).Name
|
||||||
|
}
|
||||||
|
if(!$SwitchName) {
|
||||||
|
throw "Failed to locate switch with name or ID: ${NameOrID}"
|
||||||
|
}
|
||||||
|
return $SwitchName
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Get name of VMSwitch.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
Find VMSwitch by name or ID and return name.
|
||||||
|
|
||||||
|
.PARAMETER NameOrID
|
||||||
|
|
||||||
|
Name or ID of VMSwitch.
|
||||||
|
|
||||||
|
.OUTPUT
|
||||||
|
|
||||||
|
Name of VMSwitch.
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
function Set-VagrantVMSwitch {
|
||||||
|
param (
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[Microsoft.HyperV.PowerShell.VirtualMachine] $VM,
|
||||||
|
[parameter (Mandatory=$true)]
|
||||||
|
[String] $SwitchName
|
||||||
|
)
|
||||||
|
$Adapter = Hyper-V\Get-VMNetworkAdapter -VM $VM
|
||||||
|
Hyper-V\Connect-VMNetworkAdapter -VMNetworkAdapter $Adapter -SwitchName $SwitchName
|
||||||
|
return $VM
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Configure VM to use given switch.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
Configures VM adapter to use the the VMSwitch with the given name.
|
||||||
|
|
||||||
|
.PARAMETER VM
|
||||||
|
|
||||||
|
Hyper-V VM for modification.
|
||||||
|
|
||||||
|
.PARAMETER SwitchName
|
||||||
|
|
||||||
|
Name of the VMSwitch.
|
||||||
|
|
||||||
|
.OUTPUT
|
||||||
|
|
||||||
|
VirtualMachine.
|
||||||
|
#>
|
||||||
|
}
|
|
@ -1,20 +0,0 @@
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
|
||||||
# All Rights Reserved. Licensed under the MIT License.
|
|
||||||
#--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
function Write-Error-Message($message) {
|
|
||||||
$error_message = @{
|
|
||||||
error = "$message"
|
|
||||||
}
|
|
||||||
Write-Host "===Begin-Error==="
|
|
||||||
$result = ConvertTo-json $error_message
|
|
||||||
Write-Host $result
|
|
||||||
Write-Host "===End-Error==="
|
|
||||||
}
|
|
||||||
|
|
||||||
function Write-Output-Message($message) {
|
|
||||||
Write-Host "===Begin-Output==="
|
|
||||||
Write-Host $message
|
|
||||||
Write-Host "===End-Output==="
|
|
||||||
}
|
|
Loading…
Reference in New Issue