I need to move a large number vm's fed from a csv from a host in one cluster to hosts in another cluster. I have the script below to move just the nics. But I want to incorporate vmotion and port group change either on the same line or one right after the other. Then move on to the next vm in the csv. Possibly running async to have multiple migrations happening at the same time instead of serially one after the other.
foreach($pg in Import-Csv -Path C:\temp\VMPortGroups.csv -UseCulture){
Get-VM -Name $pg.VM | Get-NetworkAdapter -Name $pg.NIC |
Set-NetworkAdapter -NetworkName $pg.Network -Confirm:$False
}
Can you try something like this?
I assume the Network column in the CSV specifies a (VDS ?) Portgroup in the destination cluster.
$target_cluster = 'CLUSTERNAME'
Import-Csv -Path C:\temp\VMPortGroups.csv -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$vm = Get-VM -Name $row.VM
$nic = Get-NetworkAdapter -VM $vm -Name $row.NIC
$pg = Get-PortGroup -Name $row.Network
Move-VM -VM $vm -Destination $target_cluster -NetworkAdapter $nic -PortGroup $pg
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Would this work?
$target_cluster = 'CLUSTERNAME'
foreach($pg in Import-Csv -Path C:\temp\VMPortGroups.csv -UseCulture){
Move-VM -VM $PG.VM -Destination $target_cluster -NetworkAdapter $pg.NIC
}
That should work
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This is what I got Luke.
Move-VM : Cannot bind parameter 'NetworkAdapter'. Cannot convert the "Network adapter 1" value of type "System.String" to type "VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.NetworkAdapter".
At line:5 char:70
+ ... $PG.VM -Destination $target_cluster -NetworkAdapter $pg.NIC -Networ ...
+ ~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Move-VM], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM
Script below
$target_cluster = 'CLUSTERNAME'
foreach($pg in Import-Csv -Path C:\temp\VMPortGroups.csv -UseCulture){
Move-VM -VM $PG.VM -Destination $target_cluster -NetworkAdapter $pg.NIC -Network $pg.Network
}
I have two datacenters in the same vCenter. And I'm trying to mass migrate a list of VM's from one cluster to another and place them on a different DVS and different port group. One thing that's a little unique is that the port groups are all Cisco ACI and have really long names. Example: Prod-Netcentrc|NetCentric|v501_v1501
I'm able to get the script to work within the same cluster. But not between the virtual datacenters and different clusters.
foreach($pg in Import-Csv -Path C:\temp\VMPortGroups.csv -UseCulture){
Get-VM -Name $pg.VM | Get-NetworkAdapter -Name $pg.NIC |
Move-VM $PG.VM -Destination $target_vhost |
Set-NetworkAdapter -NetworkName $pg.Network -Confirm:$False
}
This is the error it throughs.
Move-VM : 12/14/2022 6:53:46 PM Move-VM The operation for the entity "ACIMigrationTest01" failed with the following message: "Currently connected network interface 'Network adapter 1' uses
network 'DVSwitch: 50 13 5d 83 71 e9 60 61-ac 8a 8f 88 c6 9a 88 a6', which is not accessible."
At line:4 char:1
+ Move-VM ACIMIGRATIONTEST01 -Destination $target_vhost | Set-NetworkAd ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Move-VM], CannotAccessNetwork
+ FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpdates_OperationFailed,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM
This looks like the issue described in KB1003830
Do any of the listed possible causes in that KB apply to your environment?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I have no trouble manually moving VM's doing a live vmotion and choosing the new target dvs and new portgroup. The target DVS only lives on the target hosts. Its a Cisco ACI created DVS which is which is why the port group labels all look like this Prod-Netcentric|Netcentric|v1205. And they use different vlan ids for their tags even thought the vlan's are the same as on the source hosts.
Can you try something like this?
I assume the Network column in the CSV specifies a (VDS ?) Portgroup in the destination cluster.
$target_cluster = 'CLUSTERNAME'
Import-Csv -Path C:\temp\VMPortGroups.csv -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$vm = Get-VM -Name $row.VM
$nic = Get-NetworkAdapter -VM $vm -Name $row.NIC
$pg = Get-PortGroup -Name $row.Network
Move-VM -VM $vm -Destination $target_cluster -NetworkAdapter $nic -PortGroup $pg
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Luc
This is the error I got with that change.
Get-PortGroup : The term 'Get-PortGroup' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.
At line:7 char:9
+ $pg = Get-PortGroup -Name $row.Network
+ ~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-PortGroup:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Move-VM : Cannot bind parameter 'PortGroup'. Cannot convert the "@{VM=ACIMIGRATIONTEST05; NIC=Network adapter 1; Network=Prod-Netcentric|Netcentric|v501_v1501}" value of type
"System.Management.Automation.PSCustomObject" to type "VMware.VimAutomation.ViCore.Types.V1.Host.Networking.VirtualPortGroupBase".
At line:9 char:80
This worked. And it moved the group without issue. Thanks Luc!
Get-VirtualPortGroup
PS F:\>
$target_cluster = 'CLusterNameI'
Import-Csv -Path C:\temp\VMPortGroups.csv -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$vm = Get-VM -Name $row.VM
$nic = Get-NetworkAdapter -VM $vm -Name $row.NIC
$pg = Get-VirtualPortGroup -Name $row.Network
Move-VM -VM $vm -Destination $target_cluster -NetworkAdapter $nic -PortGroup $pg
Oops, a typo. My bad.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hello LucD,
I hope you are spending a nice evening in Barcelona, and if it's not the case wherever you are.
I did not want to open a new topic as my question it is somehow similar.
We are vmotionning vms from a dvs to another one handled by CISCO ACI.
Matching the vlan ID port group on source and destination is the only way to correctly map the destination network during the vmotion process as the distributed portgroup names are different (Thank you ACI) .
The problem I have with the code is that $sourcevlanID is somehow randomly empty sometimes and when it starts vmotion I get :
##########
Move-VM : 08/11/2023 20:30:36 Move-VM The operation for the entity "vm1" failed with the following message: "Currently connected network interface 'Network adapter 1' uses network 'DVSwitch: aa 13 27 xxx', which is not accessible."
At line:3 char:5
+ Move-VM -VM $vm -Destination $targetHost
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Move-VM], CannotAccessNetwork
+ FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpdates_OperationFailed,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM
########## here is the code########
$vmName = "vm1"
$targetHost = "hosthyper1"
$targetVDS = "VDS1"
$vm = Get-VM -Name $vmName
$sourceNetworkAdapter = $vm | Get-NetworkAdapter
$sourcePortgroupName = $sourceNetworkAdapter.NetworkName
$sourceVlanId = $sourceNetworkAdapter.ExtensionData.Config.SwitchPort.Vlan.VlanId
$targetPortGroups = Get-VDPortgroup -VDSwitch $targetVDS
$targetPortGroup = $targetPortGroups | Where-Object { $_.VlanId -eq $sourceVlanId }
if ($targetPortGroup) {
Move-VM -VM $vm -Destination $targetHost
Write-Host "VMotion started for $vmName to $targetHost."
$timeout = 600
$vmotionComplete = $false
$startTime = Get-Date
while ((Get-VM -Name $vmName | Select-Object -ExpandProperty PowerState) -ne "PoweredOn") {
if ((Get-Date) - $startTime -ge ([TimeSpan]::FromSeconds($timeout))) {
Write-Host "VMotion timed out."
break
}
Start-Sleep -Seconds 10
}
if ($vmotionComplete) {
$targetNetworkAdapter = $vm | Get-NetworkAdapter | Where-Object { $_.NetworkName -eq $sourcePortgroupName }
$targetNetworkAdapter | Set-NetworkAdapter -NetworkName $targetPortGroup.Name -Confirm:$false
Write-Host "VMotion successfully for VLAN ID $sourceVlanId"
}
} else {
Write-Host "no matching VLAN found on the target host in the specified Vvds $sourceVlanId"
}
I think the error message is quite clear.
You are trying to move the VM to an ESXi node that is not added to the VDS to which the portgroup, to which at least 1 vNIC of the VM is connected, belongs.
Since you didn't specify what should happen with the network connections, the Move-VM tries to connect the VM to the same portgroup(s) on the destination ESXi node.
You can try using the Portgroup or Network parameter on the Move-VM cmdlet.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference