Hi
I'm planning to migrate few of my clusters which are running in standard switch to DVS.Need help to automate this process.
My scenario is :
In a environment 15cluster are present 5 are already running in DVS
but 10 clusters are still in standard switch so I need to migrate them
to already existing DVSwitch.
Taking one 10node cluster as example.
1)mgmt and vmkernel are on one vswitch (ex: vswitch 0)
[vswitch 0 --- Connected with 2 vmincs ]
2)virtual machine portgroup in one vswitch (Ex: vswitch 1)
[vswitch 1 --- Connected with 2 vmincs ]
On all the clusters we need to migrate only virtual machine portgroup
or vmnetwork (ex:vswitch 1) to DVs excluding mgmt and vmkernel network.
My plan:
First add all the hosts in cluster to DVswitch
Remove any one redundant vmnic (ex:vmnic3) connected to virtual machine portgroup. (Ex: vswitch 1) and add this to DVswitch.
Now migrate all vms connected to standard switch to dvs.(Here i struck)
Is there any way if VLAN 10 (standard switch) consists of 5 VMS then
check VLAN 10 in DVS and set network adapter portgroup to VLAN 10 on the
vms (I mean can we compare VLAN IDs on VSS and VDS and based on than we
need to migrate vms to DVS.)
As below :
If it works successfully then need to check ping status of all vms (ignore powered off vms)
If ok then proceed to map second nic (ex:vmnic4) from VSS to VDS.
Used Script:
# ESXi hosts to migrate from VSS to VDS
$vmhost_array = @("host1","host2")
# Adding Hosts to existing VDswitch
$vds = Get-VDSwitch -Name "SM_UAT"
foreach ($vmhost in $vmhost_array) {
# Add ESXi host to VDS
Write-Host "Adding" $vmhost "to" $vds_name
$vds | Add-VDSwitchVMHost -VMHost $vmhost | Out-Null
# Migrate pNICs to VDS
Write-Host "Adding vmnic2 to" $vds
$vmhostNetworkAdapter = Get-VMHost $vmhost |Get-VirtualSwitch -Name "vswitch1" |select -ExpandProperty Nic |select -First 1
$vds | Add-VDSwitchPhysicalNetworkAdapter -VMHostNetworkAdapter $vmhostNetworkAdapter -Confirm:$false
# Migrate VMs from VSS to VDS
Write-Host "migrating vms from VSS to VDS"
}
Something like this
Write-Host -Object 'Fetching Second vnic connected to vswitch'
$vmCount = (Get-View (Get-View (Get-VirtualSwitch -Name vSwitch1 -VMHost $vmhost ).VMHostId).VM | where {!$_.Config.Template}).Count
if($vmCount -eq 0){
$vmhostNetworkAdapter2 = Get-VMHost $vmhost |Get-VirtualSwitch -Name 'vswitch1' | Select-Object -ExpandProperty Nic | Select-Object -First 1
Write-Host -Object 'Removing Second vnic from vswitch'
$vmhost |Get-VMHostNetworkAdapter -Name $vmhostNetworkAdapter2 |Remove-VirtualSwitchPhysicalNetworkAdapter -Confirm:$false
Write-Host -Object 'Fetching Second removed vnic into a varible'
$Phnic2 = $vmhost |Get-VMHostNetworkAdapter -Physical -Name $vmhostNetworkAdapter2
Write-Host -Object "Adding Second vmnic (redundant) to $vds"
Add-VDSwitchPhysicalNetworkAdapter -DistributedSwitch $vds -VMHostPhysicalNic $Phnic2 -Confirm:$false
}
else
{
Write-Host 'Still VMs connected to vswitch1 on $($vmhost.Name)'
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Luc I will give a try and post you back.
LucD wrote:
I can confirm (in PowerCLI 5.8R1), there seems to be indeed a "feature" in the Get-VM cmdlet with the VirtualSwitch parameter.
I too can confirm this "feature" and have logged it as an issue in our system, thanks guys!
Luc., This is not working The command you provided on the earlier post is also showing vms.
After migrating all vms from VSS to VDS the count still showing VMS currently hosted on the particular host.Not picking particular VSS like Vswitch1.
Ex:
This is the complete code :
# ESXi hosts to migrate from VSS to VDS
$vmhost_array = Get-Cluster "Call Center" |Get-VMHost
# get existing VDswitch
$vds = Get-VDSwitch -Name 'PRODUCTION _ CORP_dvSwitch'
foreach ($vmhost in $vmhost_array)
{
# Add ESXi hosts to VDS
Write-Host -Object "Adding $vmhost to $vds"
$null = $vds |Add-VDSwitchVMHost -VMHost $vmhost
# Migrate pNICs to VDS
Write-Host -Object 'Fetching First vnic connected to vswitch'
$vmhostNetworkAdapter = Get-VMHost $vmhost |Get-VirtualSwitch -Name 'vswitch1' | Select-Object -ExpandProperty Nic | Select-Object -First 1
Write-Host -Object 'Removing vnic from vswitch'
$vmhost |Get-VMHostNetworkAdapter -Name $vmhostNetworkAdapter |Remove-VirtualSwitchPhysicalNetworkAdapter -Confirm:$false
Write-Host -Object 'Fetching removed vnic into a varible'
$Phnic = $vmhost |Get-VMHostNetworkAdapter -Physical -Name $vmhostNetworkAdapter
Write-Host -Object "Adding vmnic (redundant) to $vds"
Add-VDSwitchPhysicalNetworkAdapter -DistributedSwitch $vds -VMHostPhysicalNic $Phnic -Confirm:$false
# Migrate VMs from VSS to VDS
Write-Host -Object 'Fetching virtualPortgroup info from vswitch'
$vssPG1 = $vmhost |Get-VirtualPortGroup -Standard -VirtualSwitch 'vswitch1'
Write-Host -Object 'migrating vms from VSS to VDS'
foreach($vssPG in $vssPG1)
{
$dvsPG = $vds |Get-VDPortgroup |Where-Object -FilterScript {$_.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId -eq $vssPG.VlanId}
$vmhost |Get-VM |Get-NetworkAdapter |Where-Object -FilterScript {$_.NetworkName -eq $vssPG.Name} | Set-NetworkAdapter -NetworkName $dvsPG.Name -Confirm:$false
}
# Check Ping Status
#Write-Host -Object "Check Ping Status of VMS and write output"
#$vmhost |Get-VM | Select Name,PowerState,@{N="Ping";E={
#if($_.PowerState -eq "PoweredOn" -and (Test-Connection -ComputerName $_.Name)){"Online"}else{"Offline"}}}
Write-Host -Object 'Fetching Second vnic connected to vswitch'
$vmhostNetworkAdapter2 = Get-VMHost $vmhost |Get-VirtualSwitch -Name 'vswitch1' | Select-Object -ExpandProperty Nic | Select-Object -First 1
Write-Host -Object 'Fetching Second vnic connected to vswitch for $vmhost'
$vmCount = (Get-View (Get-View (Get-VirtualSwitch -Name vSwitch1 -VMHost $vmhost ).VMHostId).VM | where {!$_.Config.Template}).Count
if($vmCount -eq 0){
$vmhostNetworkAdapter2 = Get-VMHost $vmhost |Get-VirtualSwitch -Name 'vswitch1' | Select-Object -ExpandProperty Nic | Select-Object -First 1
Write-Host -Object 'Removing Second vnic from vswitch on $vmhost'
$vmhost |Get-VMHostNetworkAdapter -Name $vmhostNetworkAdapter2 |Remove-VirtualSwitchPhysicalNetworkAdapter -Confirm:$false
Write-Host -Object 'Fetching Second removed vnic into a varible'
$Phnic2 = $vmhost |Get-VMHostNetworkAdapter -Physical -Name $vmhostNetworkAdapter2
Write-Host -Object "Adding Second vmnic (redundant) to $vds"
Add-VDSwitchPhysicalNetworkAdapter -DistributedSwitch $vds -VMHostPhysicalNic $Phnic2 -Confirm:$false
}
else
{
Write-Host 'Still VMs connected to vswitch1 on $vmhost'
}
}
=============================================================
Yes, you are right, my solution doesn't work.
Can you try if this returns the correct status, in other words, no VirtualMachine objects should be returned.
Get-VirtualSwitch -Name 'vSwitch1' -VMHost $vmhost | Get-VirtualPortGroup | Get-VM
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes you are correct.When i execute below line it doesn't written any VM as Vswitch1 contains no VM.
Get-VirtualSwitch -Name 'vSwitch1' -VMHost 10.xx.xx.xx | Get-VirtualPortGroup | Get-VM
Great, so now you have a test to determine if the original switch can be removed.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes I'm going to test Ill post here the Script after completion.
Thanks Luc finally it works as per my requirement.This is the complete code for any further reference.
# ESXi hosts to migrate from VSS to VDS
$vmhost_array = Get-Cluster |Get-VMHost
# get existing VDswitch
$vds = Get-VDSwitch -Name 'PRODUCTION _ CORP_dvSwitch'
foreach ($vmhost in $vmhost_array)
{
# Add ESXi hosts to VDS
Write-Host -Object "Adding $vmhost to $vds"
$null = $vds |Add-VDSwitchVMHost -VMHost $vmhost
# Migrate pNICs to VDS
Write-Host -Object 'Fetching First vnic connected to vswitch'
$vmhostNetworkAdapter = Get-VMHost $vmhost |Get-VirtualSwitch -Name 'vswitch2' | Select-Object -ExpandProperty Nic | Select-Object -First 1
Write-Host -Object 'Removing vnic from vswitch'
$vmhost |Get-VMHostNetworkAdapter -Name $vmhostNetworkAdapter |Remove-VirtualSwitchPhysicalNetworkAdapter -Confirm:$false
Write-Host -Object 'Fetching removed vnic into a varible'
$Phnic = $vmhost |Get-VMHostNetworkAdapter -Physical -Name $vmhostNetworkAdapter
Write-Host -Object "Adding vmnic (redundant) to $vds"
Add-VDSwitchPhysicalNetworkAdapter -DistributedSwitch $vds -VMHostPhysicalNic $Phnic -Confirm:$false
# Migrate VMs from VSS to VDS
Write-Host -Object 'Fetching virtualPortgroup info from vswitch'
$vssPG1 = $vmhost |Get-VirtualPortGroup -Standard -VirtualSwitch 'vswitch2'
Write-Host -Object 'migrating vms from VSS to VDS'
foreach($vssPG in $vssPG1)
{
$dvsPG = $vds |Get-VDPortgroup |Where-Object -FilterScript {$_.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId -eq $vssPG.VlanId}
$vmhost |Get-VM |Get-NetworkAdapter |Where-Object -FilterScript {$_.NetworkName -eq $vssPG.Name} | Set-NetworkAdapter -NetworkName $dvsPG.Name -Confirm:$false
}
# Check Ping Status
#Write-Host -Object "Check Ping Status of VMS and write output"
#$vmhost |Get-VM | Select Name,PowerState,@{N="Ping";E={
#if($_.PowerState -eq "PoweredOn" -and (Test-Connection -ComputerName $_.Name)){"Online"}else{"Offline"}}}
Write-Host -Object 'Fetching Second vnic connected to vswitch'
$vmhostNetworkAdapter2 = Get-VMHost $vmhost |Get-VirtualSwitch -Name 'vswitch2' | Select-Object -ExpandProperty Nic | Select-Object -First 1
Write-Host -Object 'Fetching Second vnic connected to vswitch for $vmhost'
$vmCount = (Get-VirtualSwitch -Standard -Name 'vSwitch2' -VMHost $vmhost |Get-VirtualPortGroup | Get-VM).count
if($vmCount -eq 0){
$vmhostNetworkAdapter2 = Get-VMHost $vmhost |Get-VirtualSwitch -Name 'vswitch2' | Select-Object -ExpandProperty Nic | Select-Object -First 1
Write-Host -Object 'Removing Second vnic from vswitch on $vmhost'
$vmhost |Get-VMHostNetworkAdapter -Name $vmhostNetworkAdapter2 |Remove-VirtualSwitchPhysicalNetworkAdapter -Confirm:$false
Write-Host -Object 'Fetching Second removed vnic into a varible'
$Phnic2 = $vmhost |Get-VMHostNetworkAdapter -Physical -Name $vmhostNetworkAdapter2
Write-Host -Object "Adding Second vmnic (redundant) to $vds"
Add-VDSwitchPhysicalNetworkAdapter -DistributedSwitch $vds -VMHostPhysicalNic $Phnic2 -Confirm:$false
}
else
{
Write-Host 'Still VMs connected to vswitch2 on' $vmhost
}
}
WOW LucD, you are just all over the place and with a bevy of good info, your scripting has really saved me a lot of time.
I just left you a comment on the "compatibility topic" thread you have going as well...Great work!
Have a question on the this script. When I run I see a mix of continuous errors and success I think, Seems to move all the vm's have a few phantom ones however that appear in the console, but when/if you check the settings are are indeed located on the same vmpg located on the vds. Please see the picture below and respond with any comments on why I'm seeing the errors, on theory is that if if finds the PG name on the vds and vss that if that vss pg is empty (no vm's) that it throws and error, but cant be sure, btw I'm using powercli 10.
Set-NetworkAdapter : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'NetworkName'. Specified method is not supported.At line:23 char:41
+ } | Set-NetworkAdapter -NetworkName $dvsPG.Name -Confirm:$false
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-NetworkAdapter], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,VMware.VimAutomation.ViCore.Cmdlets.Commands.VirtualDevice.SetNetworkAdapter
That error seems to indicate that you have an array in $dvsPG, more than 1 entry.
Or you have multiple portgroups with the same VLANid, or you might be connected to multiple vSphere servers (check the content of $global:defaultviservers).
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
What I'm doing is moving vm's from multiple vmpg's on a single vss to multiple vmpg's on a vds, the vmpg names are indeed like names and vlanID's.
Is that the issue?
The NetworkName parameter expects a single value (1 portgroupname), and you seem to be passing multiple names (an array).
If you have multiple portgroupnames, you would need to do that in a loop, and use one name at the time.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Also found something else wrong with the above script, however now exactly sure yet how to combat. Keep in mind initially this worked perfectly on my first cluster, however on my second cluster that vds I was moving vm's to contained a unique vmpg that utilized "Private VLAN" using Promiscuous Mode (200, 200). my guess is that because set to Promiscuous, the line 16 above in script was tagged for only that particular vlan, therefore every vm that was on the vss was sent to that vmpg on the VSS. Note, that vmpg didn't even exist on the vss, however feel like 16 above and the use of Promicuous forced all vm's to that vmpg on the vss.. So things to consider and guard against in future, my fix for the remain hosts in cluster as I only used one host to start was to edit the vss promiscuous vmpg to vlan ?? and then it worked correctly....
You are correct, that code did not handle PVLANs.
To handle those would need additional logic in the script.
And I suspect that trunked VLANs might not be handled correctly either.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD
I'm trying to do something very much like this but the reverse, VDS to VSS in only one of my clusters.
I am Migrating to a new vcenter...v5 U3 to v6 U2....So I have to get all vm's on V5 to VSS then relocate to my V6 env and then move back to VDS.
I see scripts out there that look to do much of the work and in most cases using the wizard in networking Migrate VM networking works for me, however in one vds i have over a hundred vm's spread across 100 port groups on the vds, making that one by one very long process. In my case I've already build out the vss (vSwitch35) with all the port groups that exist on the vds (Eng Lab dvswitch).
Any script out there that will look at look at a vds, and relocate all vm's on this vds to a vss that has the same port group and vlan IDs?
Try something like this
$vdsName = 'Eng Lab'
$vssName = 'vSwitch35'
Get-VDSwitch -Name $vdsName | Get-VDPortgroup -PipelineVariable pg | Get-VM -PipelineVariable vm |
ForEach-Object -Process {
$vss = Get-VirtualSwitch -Name $vssName -VMHost $vm.VMHost
$vssPg = Get-VirtualPortGroup -Name $pg.Name -VirtualSwitch $vss
Get-NetworkAdapter -VM $vm | where{$_.NetworkName -eq $pg.Name} |
Set-NetworkAdapter -Portgroup $vssPg -Confirm:$false
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference