It was failing to create files below the machines\default\hyperv folder, rather it was creating folders named 'hypervSnapshots', 'hypervVirtual Hard Disks', and 'hypervVirtual Machines'. This was causing the files to not be removed when destroying the vm, and an error when subsequently bringing it up again.
164 lines
4.6 KiB
PowerShell
164 lines
4.6 KiB
PowerShell
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]$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]$differencing_disk=$null
|
|
)
|
|
|
|
"$($data_path)/Snapshots"
|
|
|
|
# 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
|
|
$VmProperties = @{
|
|
Path = $vm_config_file
|
|
SnapshotFilePath = Join-Path $data_path 'Snapshots'
|
|
VhdDestinationPath = Join-Path $data_path 'Virtual Hard Disks'
|
|
VirtualMachinePath = Join-Path $data_path 'Virtual Machines'
|
|
}
|
|
|
|
$vmConfig = (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 = (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
|
|
}
|
|
|
|
|
|
Connect-VMNetworkAdapter -VMNetworkAdapter (Get-VMNetworkAdapter -VM $vmConfig.VM) -SwitchName $switchname
|
|
Set-VM -VM $vmConfig.VM -NewVMName $vm_name -MemoryStartupBytes $MemoryStartupBytes
|
|
Set-VM -VM $vmConfig.VM -MemoryMinimumBytes $MemoryMinimumBytes -MemoryMaximumBytes $MemoryMaximumBytes
|
|
Set-VM -VM $vmConfig.VM -ErrorAction "Stop" -ProcessorCount $processors
|
|
|
|
If ($dynamicmemory) {
|
|
Set-VM -VM $vmConfig.VM -DynamicMemory
|
|
} else {
|
|
Set-VM -VM $vmConfig.VM -StaticMemory
|
|
}
|
|
|
|
if ($notes) {
|
|
Set-VM -VM $vmConfig.VM -Notes $notes
|
|
}
|
|
|
|
if ($auto_start_action) {
|
|
Set-VM -VM $vmConfig.VM -AutomaticStartAction $auto_start_action
|
|
}
|
|
|
|
if ($auto_stop_action) {
|
|
Set-VM -VM $vmConfig.VM -AutomaticStartAction $auto_stop_action
|
|
}
|
|
|
|
# Only set EFI secure boot for Gen 2 machines, not gen 1
|
|
if ($generation -ne 1) {
|
|
Set-VMFirmware -VM $vmConfig.VM -EnableSecureBoot (Get-VMFirmware -VM $vmConfig.VM).SecureBoot
|
|
}
|
|
|
|
$report = Compare-VM -CompatibilityReport $vmConfig
|
|
if($report.Incompatibilities.Length -gt 0){
|
|
$report.Incompatibilities
|
|
Write-Error-Message ConvertTo-Json $report.Incompatibilities
|
|
}
|
|
|
|
# Differencing disk
|
|
if($differencing_disk){
|
|
# 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){
|
|
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
|
|
Remove-VMHardDiskDrive $drive
|
|
New-VHD -Path $dest_path -ParentPath $source_path -ErrorAction Stop
|
|
Add-VMHardDiskDrive -VM $vmConfig.VM -Path $dest_path
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Import-VM -CompatibilityReport $vmConfig
|
|
|
|
$vm_id = (Get-VM $vm_name).id.guid
|
|
$resultHash = @{
|
|
name = $vm_name
|
|
id = $vm_id
|
|
}
|
|
|
|
$result = ConvertTo-Json $resultHash
|
|
Write-Output-Message $result
|