First I have to thank LucD and Avlieshout for their posts and help.
I was given a task of moving hundreds of systems to new nfs storage volumes. And as usual it had to be done yestersday. It worked out great and I was able to finish in about two weeks. I figured I would share what I put together based on code posted by Avlieshout.
# ===============================================================
# SCRIPT NAME: svmotion.ps1
# AUTHOR:
# MANAGER:
# DATE:
# COMMENT:
# VERSION: 1.0
# REVISIONS:
# ===============================================================
Clear-Host
$vCenter = Read-Host 'Enter vCenter Server Name'
$name = Read-Host 'Enter Username [domain\Username]'
$pwd = Read-Host 'Enter Password'
Clear-Host
Connect-VIServer $vCenter -User $name -Password $pwd
Clear-Host
do {
Write-Host " "
$targetVM = Read-Host 'Enter Machine to SVMotion'
$vm = Get-VM $targetVM
Write-Host "*** SVMotion Script for $vm ***" -foregroundcolor Yellow
$response = Read-Host 'Enter Number of Hard Disks [1-4]'
switch ($response) {
1 {
$HardDisk1DatastoreName = Read-Host 'Enter "Hard Disk 1" Target Location '
$configDatastoreName = $HardDisk1DatastoreName
Write-Host "SVMotion Started for $vm " -ForegroundColor Red
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.Datastore = (Get-Datastore $configDatastoreName | Get-View).MoRef
#HardDisk 1
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[0].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk1DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#When all harddisks are specified call the RelocateVM_task()
$vm.ExtensionData.RelocateVM_Task($spec, "defaultPriority")
break
Clear-Host
}
2 {
$HardDisk1DatastoreName = Read-Host 'Enter "Hard Disk 1" Target Location '
$configDatastoreName = $HardDisk1DatastoreName
$HardDisk2DatastoreName = Read-Host 'Enter "Hard Disk 2" Target Location '
Write-Host "SVMotion Started for $vm " -ForegroundColor Red
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.Datastore = (Get-Datastore $configDatastoreName | Get-View).MoRef
#HardDisk 1
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[0].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk1DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#HardDisk 2
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[1].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk2DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#When all harddisks are specified call the RelocateVM_task()
$vm.ExtensionData.RelocateVM_Task($spec, "defaultPriority")
break
Clear-Host
}
3 {
$HardDisk1DatastoreName = Read-Host 'Enter "Hard Disk 1" Target Location '
$configDatastoreName = $HardDisk1DatastoreName
$HardDisk2DatastoreName = Read-Host 'Enter "Hard Disk 2" Target Location '
$HardDisk3DatastoreName = Read-Host 'Enter "Hard Disk 3" Target Location '
Write-Host "SVMotion Started for $vm " -ForegroundColor Red
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.Datastore = (Get-Datastore $configDatastoreName | Get-View).MoRef
#HardDisk 1
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[0].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk1DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#HardDisk 2
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[1].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk2DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#HardDisk 3
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[2].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk3DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#When all harddisks are specified call the RelocateVM_task()
$vm.ExtensionData.RelocateVM_Task($spec, "defaultPriority")
break
Clear-Host
}
4 {
$HardDisk1DatastoreName = Read-Host 'Enter "Hard Disk 1" Target Location '
$configDatastoreName = $HardDisk1DatastoreName
$HardDisk2DatastoreName = Read-Host 'Enter "Hard Disk 2" Target Location '
$HardDisk3DatastoreName = Read-Host 'Enter "Hard Disk 3" Target Location '
$HardDisk4DatastoreName = Read-Host 'Enter "Hard Disk 4" Target Location '
Write-Host "SVMotion Started for $vm " -ForegroundColor Red
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.Datastore = (Get-Datastore $configDatastoreName | Get-View).MoRef
#HardDisk 1
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[0].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk1DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#HardDisk 2
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[1].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk2DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#HardDisk 3
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[2].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk3DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#HardDisk 4
$objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $vm.HardDisks[3].Id.Split('/')[1]
$objDisk.DataStore = (Get-Datastore $HardDisk4DatastoreName | Get-View).MoRef
$spec.Disk += $objDisk
#When all harddisks are specified call the RelocateVM_task()
$vm.ExtensionData.RelocateVM_Task($spec, "defaultPriority")
break
Clear-Host
}
0 {
Write-Host "Exiting Script"
break
}
default {
"** The selection could not be determined **"
break
}
}
}
while ($response -ne "0")
Thank you for sharing and glad to hear that everything worked out fine!
Arnim
Hi Arnim, again I can't thank you enough for all the help you provided me via this community.
The script mentioned here, based on your code, worked like a charm as I mentioned; however, I just upgraded to the latest version of PowerCLI (VMware-PowerCLI-4.1.1-332441) and now the script doesn't work due to obsolete property.
Here is the error:
WARNING: 'HardDisks' property is obsolete. Use 'Get-HardDisk' cmdlet instead.
Exception calling "RelocateVM_Task" with "2" argument(s): "Not initialized: vim.Datastore datastore"
At C:\scripts\svmotion.ps1:45 char:34
+ $vm.ExtensionData.RelocateVM_Task <<<< ($spec, "defaultPriority")
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
I'm hoping it's a small change.
Thank you very much,
Robert
Hi Robert,
There are in fact 2 different messages.
The first one is a warning about the Harddisks property, which is annoying but doesn't make your script fail.
The 2nd on says that the datastore property in the $spec variable is not initialised properly.
Could it be that the first datastore name you entered was incorrect by any chance ?
I tested it and for me it all works.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I made some changes to your script to avoid the warning and to use the PowerCLI 4.1u1 features
# ===============================================================
# SCRIPT NAME: svmotion.ps1
# AUTHOR:
# MANAGER:
# DATE:
# COMMENT:
# VERSION: 1.0
# REVISIONS:
# ===============================================================
Clear-Host
$vCenter = Read-Host 'Enter vCenter Server Name'
$name = Read-Host 'Enter Username [domain\Username]'
$pwd = Read-Host 'Enter Password'
Clear-Host
Connect-VIServer $vCenter -User $name -Password $pwd
Clear-Host do { Write-Host " "
$targetVM = Read-Host 'Enter Machine to SVMotion (q to quit)'
if($targetVM -ne "q"){ $vm = Get-VM $targetVM
Write-Host "*** SVMotion Script for $vm ***" -foregroundcolor Yellow
$HardDisks = @(Get-HardDisk -VM $vm) Write-Host "SVMotion Started for $vm " -ForegroundColor Red
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
1..$HardDisks.Count | %{ $dsName = Read-Host ('Enter "Hard Disk ' + $_ + '" Target Location ') if($_ -eq 1){ $spec.Datastore = (Get-Datastore $dsName).Extensiondata.MoRef } $objDisk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$objDisk.DiskID = $HardDisks[$_ - 1].Id.Split('/')[1] $objDisk.DataStore = (Get-Datastore $dsName).Extensiondata.MoRef $spec.Disk += $objDisk } $vm.ExtensionData.RelocateVM_Task($spec, "defaultPriority") Clear-Host
} } until($targetVM -eq "q")
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD, thank you for helping me out yet again. The improvements you made to the script are perfect. The one big thing lacking from the old version was having the guest disk count prior to execution. What a time saver. Awesome!