# Assumptions:
# - Guest VM files are stored at a single location
# - The service account or admin user has access to source and destination
# - Source and destination storage paths are joined to the same domain
$vmName='TESTWINDOWS'
$sourceStorage='C:\ClusterStorage\Blob1\TESTWINDOWS'
$destinationStorage='\\LAX-SMB1\VMS\TESTWINDOWS'
# step 1: Stop VM at Source and copy its files to Destination Storage
$vm=try{get-vm $vmName}catch{$null}
if($null -ne $vm){
stop-vm $vmName -force -Confirm:$false
# Remove-VM -VM $vm -DeletePermanently:$false -Confirm:$false # Unregister VM
robocopy $sourceStorage $destinationStorage /E /R:0 /NP
}else{
write-warning "$vmName is not found."
}
# Step 2: Register VM at destination
$parentPath='\\LAX-SMB1\VMS\TESTWINDOWS'
$vmPath=join-path $parentPath '\Virtual Machines\'
$vmcxFile=(gci $vmpath|?{$_.extension -like '.vmcx'}).FullName
Import-VM -Path $vmcxFile -copy $parentPath -GenerateNewId
# Step 3: Make adjustments
# While disconnected from network, run this command within the Windows VM
C:\Windows\System32\Sysprep\sysprep.exe /generalize
# Connect VM to the correct subnet / vlan
# Join to domain if necessary
# Verify that all disks are attached
# Step 4: Add vm into cluster
$vmName='TESTWINDOWS'
$targetCluster=(get-cluster).Name
function addVmToCluster{
param($vmName,$targetCluster)
try{
if(!$targetCluster){
$targetCluster=(get-cluster -ea SilentlyContinue).Name
}
if($targetCluster){
Add-ClusterVirtualMachineRole -Cluster $targetCluster -VirtualMachine $vmName -EA Stop
return $true
}
else{
write-host "No clusters defined."
return $false
}
}
catch{
write-warning "$($error[0])"
return $false
}
}
addVmToCluster $vmName $targetCluster
Categories: