Hello,
The purpose of this script is to vMotion all of the VMs in the input CSV ($MigrationCSVPath) to a new cluster, new datastore or datastore cluster, and also change from a virtual switch PG to a distributed switch port group with the same name.
I'm having an issue with this script where it doesn't seem to work for every VM. The script will work for some VM's but not for others and I'm not sure why. The input file for the list of VM's to be migrated looks like this:
#TYPE Selected.VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl
"Name","Id","Folder"
"servername","VirtualMachine-vm-36942","Folder3"
The error that I receive is:
Move-VM Object reference not set to an instance of an object.
At C:\MigrateScript.ps1:61 char:5
Move-VM -VM (Get-VM -Id $VM.Id) -destination $DestinationCluster ..
+ CategoryInfo: NotSpecified: (:) [Move-VM], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM
I suspect it has something to do with the network adapters but haven't been able to determine a solution yet.
Param (
[parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true, HelpMessage='Type vCenter server IP or FQDN you want to connect')]
[alias('vc')]
[String]$vCenter,
[parameter(Position=1, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, HelpMessage='Type Destination Cluster')]
[alias('c')]
[String]$DestinationCluster,
[parameter(Position=2, Mandatory=$true, ValueFromPipelineByPropertyName=$true, HelpMessage='Type name of DS_DSC')]
[alias('ds')]
[String]$DestinationDS_DSC,
[parameter(Position=3, Mandatory=$true, ValueFromPipelineByPropertyName=$true, HelpMessage='Type maximum number of parallel vmotions to allow')]
[alias('mpv')]
[String]$MaxParallelvMotion,
[parameter(Position=4, Mandatory=$true, ValueFromPipelineByPropertyName=$true, HelpMessage='Path to CSV Containing VM Names to Migrate')]
[alias('mcv')]
[String]$MigrationCSVPath,
[parameter(Position=5, Mandatory=$true, ValueFromPipelineByPropertyName=$true, HelpMessage='Type target virtual switch name')]
[alias('dvs')]
[String]$TargetSwitch
)
Process {
if ($global:DefaultVIServers.Name -notcontains $vCenter) {
try {
Connect-VIServer $vCenter -ErrorAction Stop
}
catch {
Write-Host $($Error[0].Exception) -ForegroundColor Red
break
}
}
try {
$ClusterInfo = Get-Cluster $DestinationCluster -ErrorAction Stop
if(Get-Datastore $DestinationDS_DSC){
$Datastore = Get-Datastore $DestinationDS_DSC
}
else{
$Datastore = Get-DatastoreCluster $DestinationDS_DSC
}
}
catch {
Write-Host $($Error[0].Exception) -ForegroundColor Red
break
}
#CSV requires one column with label "Name".
$VMsToRelocate = Import-Csv -path $MigrationCSVPath
foreach ($VM in $VMsToRelocate)
{
$networkadapters = Get-NetworkAdapter -VM $VM.Name
$destinationPortGroup = Get-VDPortgroup -VDSwitch $TargetSwitch -Name $networkadapters.NetworkName
$networkadapters | Format-Table -AutoSize
$destinationPortGroup | Format-Table -AutoSize
Write-Host "Relocating VM:" $VM.Name "to" $DestinationDS_DSC
Move-VM -VM (Get-VM -Id $VM.Id) -destination $DestinationCluster -NetworkAdapter $networkadapters -PortGroup $destinationPortGroup -datastore $Datastore -RunAsync
do
{
sleep 5
} while((Get-Task -Status Running | where{$_.Name -eq 'RelocateVM_Task'}).Count -gt $MaxParallelvMotion)
} #end of foreach