Last active
January 5, 2021 21:59
-
-
Save nickrsan/b2c889e2cda888262f6218fe423180cc to your computer and use it in GitHub Desktop.
Clone Hyper-V VM to same server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ProductionVMName = "DAP_Production" | |
$StagingVMName = "DAP_Staging" | |
$ExportFolder = "C:/HyperVExports" # I created a folder that removed all permissions for users - could add anyone with hyper-v permissions to a group with read/write here, along with System | |
$ExportToFolder = "$ExportFolder/$ProductionVMName/" | |
$ImportToFolder = "$ExportFolder/$StagingVMName/" | |
# caution, deletes existing exports in the next block. The try/catch doesn't work as intended. It was supposed to abandon it if it can't find the staging VMs, but proceeds through each step. Needs some work there. | |
try{ | |
Get-VM -Name $StagingVMName # (not true, but this was the design): this will throw an exception if it doesn't exist, so the following lines in this block won't run | |
Stop-VM -Name $StagingVMName -TurnOff # Turn of the VM forcibly - it's fine if it gets corrupted - we're about to destroy it | |
Get-VMHardDiskDrive -VMName $StagingVMName | Remove-VMHardDiskDrive # delete the disks - Remove-VM won't do that | |
Get-VM $StagingVMName | Remove-VM # now delete the VM | |
Remove-Item "$ExportFolder/$ProductionVMName" # remove the folder that hosted the Production VM to prevent conflicts - it's keyed by the production VM name | |
Remove-Item "$ExportFolder/$StagingVMName" # remove the folder that hosted the Staging VM imported to prevent conflicts - it's keyed by the production VM name | |
}catch{ | |
print "No existing VM - proceeding" | |
} | |
print "exporting VM" | |
Export-VM -Name $ProductionVMName -Path $ExportFolder | |
$exported_vm_path = "$ExportToFolder/Virtual Machines/" # it'll be put into a folder in the export folder with the name of the source VM | |
$exported_vm = Get-ChildItem -Path $exported_vm_path -Filter *.vmcx | Select Name # find the VM config file | |
$exported_vm_file = $exported_vm.Name | |
# import the VM and set the paths to copy everything to so we don't conflict with production VM. Store the returned object so we can rename the VM | |
$imported_vm = Import-VM -Path "$ExportToFolder/Virtual Machines/$exported_vm_file" -Copy -GenerateNewId -VirtualMachinePath $ImportToFolder -VhdDestinationPath $ImportToFolder -SnapshotFilePath $ImportToFolder -SmartPagingFilePath $ImportToFolder | |
Rename-VM -VM $imported_vm -NewName $StagingVMName | |
Set-VMNetworkAdapter -VMName $StagingVMName -DynamicMacAddress # make sure the MAC address is dynamic so we don't interfere the production server's IP | |
Get-VM $StagingVMName | Remove-VMSnapshot # remove all snapshots/checkpoints of the staging VM - we don't need them | |
Start-VM -VMName $StagingVMName # start it, but then we'll shut it down and restart it which should cause the OS to notice a hardware/network change if it was running when snapshotted | |
Stop-VM -VMName $StagingVMName | |
Start-VM -VMName $StagingVMName | |
# Get the IP address of the new machine. need to wait before running this - won't work on linux guests without installing a hyper-v daemon | |
$ips = Get-VM -Name $StagingVMName |Select -ExpandProperty Networkadapters |Select IPAddresses | |
print $ips |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For use as a guideline/getting started for others' needs - meant to duplicate the VM on the same host, particularly for creating a staging VM from a live production server VM. It attempts to delete any existing exports before running, so look out for that! Note that the VM must be copied twice in this configuration when it copies to the same server, so the server needs at least 2x the current VMs storage requirements in additional space it's using. Once to export it and another to import it - since it's being imported on the same server as the original, it needs a new ID, and that can only be done with a copy, not inplace.