From b041c1955ce0116b08e18f5398d72c43d95ad3f4 Mon Sep 17 00:00:00 2001 From: Bjorn Brala Date: Sun, 2 Oct 2016 16:10:16 +0200 Subject: [PATCH] Add support for vmcx files, new binary format for Hyper-V configurations. --- .../hyperv/scripts/import_vm_vmcx.ps1 | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 diff --git a/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 b/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 new file mode 100644 index 000000000..33c961e33 --- /dev/null +++ b/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 @@ -0,0 +1,167 @@ +Param( + [Parameter(Mandatory=$true)] + [string]$vm_config, + [Parameter(Mandatory=$true)] + [string]$image_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 +) + +# Include the following modules +$Dir = Split-Path $script:MyInvocation.MyCommand.Path +. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1")) + +# load the config from the vmcx and make a copy for editing, use TMP path so we are sure there is no vhd at the destination +$vmConfig = (Compare-VM -Copy -Path $vm_config -GenerateNewID -VhdDestinationPath $env:Temp) + +$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 = (Get-VMProcessor -VM $vmConfig.VM).Count + +}else { + $processors = $cpus +} + +function GetUniqueName($name) { + 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 = Get-VMMemory -VM $vmConfig.VM + $dynamicmemory = $configMemory.DynamicMemoryEnabled + + # Memory values need to be in bytes + $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 (!$switchname) { + $switchname = (Get-VMNetworkAdapter -VM $vmConfig.VM).SwitchName +} + +$vm_params = @{ + Name = $vm_name + NoVHD = $True + MemoryStartupBytes = $MemoryStartupBytes + SwitchName = $switchname + ErrorAction = "Stop" +} + +# Generation parameter was added in ps v4 +if((get-command New-VM).Parameters.Keys.Contains("generation")) { + $vm_params.Generation = $generation +} + +# Create the VM using the values in the hash map +$vm = New-VM @vm_params + +$notes = $vmConfig.VM.Notes + +# 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 | Set-VM @more_vm_params -Passthru + +# Only set EFI secure boot for Gen 2 machines, not gen 1 +if ($generation -ne 1) { + Set-VMFirmware -VM $vm -EnableSecureBoot (Get-VMFirmware -VM $vmConfig.VM).SecureBoot +} + +# Get all controller on the VM, first scsi, then IDE if it is a Gen 1 device +$controllers = Get-VMScsiController -VM $vmConfig.VM +if($generation -eq 1){ + $controllers = @($controllers) + @(Get-VMIdeController -VM $vmConfig.VM) +} + +foreach($controller in $controllers){ + foreach($drive in $controller.Drives){ + $addDriveParam = @{ + ControllerNumber = $drive.ControllerNumber + Path = $image_path + } + if($drive.PoolName){ + $addDriveParam.Add("ResourcePoolname",$drive.PoolName) + } + + # If the drive path is set, it is a harddisk, only support single harddisk + if ($drive.Path) { + $addDriveParam.add("ControllerType", $ControllerType) + $vm | Add-VMHardDiskDrive @AddDriveparam + } + } +} + +$vm_id = (Get-VM $vm_name).id.guid +$resultHash = @{ + name = $vm_name + id = $vm_id +} + +$result = ConvertTo-Json $resultHash +Write-Output-Message $result