Hey scripters! I recently had a task of migrating an entire virtual datacenter from one vCenter to another. It sounds like a pretty simple task, but manually recreating the cluster(s) could cause some human errors. I decided to write a script that would look at a specific vDatacenter and get all it’s clusters, then recreate that tree in the new vCenter. It’s pretty simple, really, it pulls all the clusters, then creates new clusters with the same attributes. When moving over the hosts, it first disconnects them from the original vCenter, then removes them from inventory.
I thought about disabling HA & DRS on the source vCenter cluster right before hand, but manually disconnecting & removing shouldn’t be an issue. If you add the host to the new vCenter without first removing from the old vCenter, that’s when you’ll get some HA weirdness because the old vCenter doesn’t know what just happened.
What does it do?
Simple. It looks that the vDatacenter name provided, gets all clusters & host in it. From there, it creates a new vDatacenter with the same name in the new vCenter, then recreates all the clusters. Here it actually uses the attributes of the original cluster when creating the new ones to get them as close as possible. Last, it adds the hosts back to their cluster, but in the new vCenter.
One nice thing is it also handles EVC mode.
If you have a central password repository, you could have the script pull from there, but I just had it prompt for username & password to add to the new vCenter.
What it doesn’t do.
- Resource Pools
- Permissions
- DRS Rules & Groups
- DRS Automated Migration Threshold
- Or any other advanced cluster settings
It looks at the basic cluster settings that you can set via PowerCLI when creating a cluster. It does enable HA & DRS, but anything advanced, you’ll have to adjust.
I tried the resource pools thing, it’s kind of tricky, but hopefully I’ll get that going soon. I tried the same approach as the clusters, powershell/powercli complained about a few things, no matter how I did it.
Permissions should be easy, but will really depend on the new vCenter if all the roles & if everything’s set up identical.
DRS Rules & Groups shouldn’t be that hard, but I haven’t messed with it, and unfortunately, there’s no PowerCLI access to the migration threshold. You know, that little slider with “Conservative” and “Aggressive”, it just plops it right in the middle.
Where’s the script?
Right here (DOWNLOAD):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# Written by Luke Huckaba # http://thephuck.com # @thephuck # # v0.1 - 20140429 # param([string]$vDC, [string]$srcvcenter, [string]$destvcenter) if((-not($vDC)) -and (-not($vcenter))){Throw "You must supply a vDatacenter and vCenter: -vDC ###### -vcenter vcentername"} $ErrorActionPreference = "SilentlyContinue" Add-PSSnapin VMware.* if($global:DefaultVIServer){Disconnect-VIServer -Server * -Force -Confirm:$false} connect-viserver $srcvcenter $vdatacenter = get-datacenter $vDC $clusters = get-cluster -lo $vdatacenter $VMhosts = get-vmhost -lo $vdatacenter foreach($VMhost in $VMhosts){ Get-VMHost $VMhost | Set-VMHost -State Disconnected | Remove-VMHost -Confirm:$false } Disconnect-VIServer -Server * -Force -Confirm:$false connect-viserver $destvCenter New-Datacenter $vDC -lo Datacenters if($clusters){ foreach($cluster in $clusters){ New-Cluster -HARestartPriority $cluster.HARestartPriority -HAIsolationResponse $cluster.HAIsolationResponse -VMSwapfilePolicy $cluster.VMSwapfilePolicy -Name $cluster.Name -Location $vDatacenter.Name -HAEnabled -HAAdmissionControlEnabled -HAFailoverLevel $cluster.HAFailoverLevel -DrsEnabled -DrsMode $cluster.DrsMode -DrsAutomationLevel $cluster.DrsAutomationLevel -EVCMode $cluster.EVCMode } } Foreach($VMhost in $VMhosts){ $esx_host_creds = $host.ui.PromptForCredential("ESXi Credentials Required", "Please enter credentials to log into the ESXi host.", "", "") if($clusters){ Add-VMHost -Name $VMhost.Name -Location $VMhost.Parent -Credential $esx_host_creds -Force:$true } else{ Add-VMHost -Name $VMhost.Name -Location $vdatacenter -Credential $esx_host_creds -Force:$true } } |
Have fun, and happy scripting!!!
Should the location specified in your get-cluster and get-vm commands be $vdatacenter instead of $folder?
You’re exactly right. I scrubbed this script from what I had to do at work, so some lines got removed and left remnants of that. Thanks for pointing it out!
I had some trouble getting this to work in PowerCLI 6.0. I’ve modified the cluster creation section so that it successfully brings over all the values supported by New-Cluster and Set-Cluster in a way that will work reliably, and it will also correctly set SwitchParameter properties based on the source cluster.
if($clusters){
foreach($cluster in $clusters){
Write-Host “Creating cluster $cluster.Name”
# New-Cluster doesn’t support all the things it claims to. These values all appear to work on PowerCLI 6.0r2 upon cluster creation
New-Cluster -Name $cluster.Name -Location $vdatacenter.Name -DrsEnabled:$cluster.DrsEnabled -EVCMode $cluster.EVCMode -HAEnabled:$cluster.HAEnabled -VsanEnabled:$cluster.VsanEnabled
# Now set other values as possible
Get-Cluster -Name $cluster.Name | Set-Cluster -Confirm:$false -HARestartPriority $cluster.HARestartPriority -HAIsolationResponse $cluster.HAIsolationResponse -HAAdmissionControlEnabled $cluster.HAAdmissionControlEnabled -VMSwapfilePolicy $cluster.VMSwapfilePolicy -DrsAutomationLevel $cluster.DrsAutomationLevel -VsanDiskClaimMode $cluster.VsanDiskClaimMode
# HAFailoverLevel cannot be set to 0. Set the value if it’s not 0.
if ($cluster.HAFailoverLevel) {Get-Cluster -Name $cluster.Name | Set-Cluster -Confirm:$false -HAFailoverLevel $cluster.HAFailoverLevel}
}
}
As another reader noted, there appears to have been errors introduced while sanitizing this script for publication. The parameter checking line appears to have been copied from another script and references values that aren’t set here.
I need to revisit this to clean it up and make it work better, I just haven’t had the time :(