VMware Cloud Community
bgallagher72
Contributor
Contributor
Jump to solution

PowerCLI to change network from standard vSwitch to Distributed vSwitch

I am working on a deployment script to build my VMs from a template. After its built I need to change the network over to a dvSwitch. I need help to figure out the correct syntex.

This did not work:

$vmname = test2008_11

$vlan = XXX_XX_57_x

Get-vm $vmname | Get-NetworkAdapter | Set-NetworkAdapter -StartConnected $true -DistributedSwitch dvSwitch1 -NetworkName $vlan -Confirm:$false

Here is the info from powerCLI

PowerCLI > Get-VirtualSwitch -Name dvSwitch1

Name            NumPorts   Num Ports  Mtu   Key                            Notes
                           Available
----            --------   ---------- ---   ---                            -----
dvSwitch1       2474                  1500  cf b2 12 50 f2 a5 1c b5-64 ...


PowerCLI C:\Users\bxg4211\Documents\PowerCli\Deploy> Get-VirtualSwitch -Name dvSwitch1 | Get-VirtualPortGroup

Name                      Key                            VLanId PortBinding NumPorts
----                      ---                            ------ ----------- --------
XXX_XX_61_x               dvportgroup-12662                     Static      128
XXX_XX_50_x               dvportgroup-12676                     Static      128
XXX_XX_44_x               dvportgroup-12675                     Static      128
dvSwitch1-DVUplinks-12654 dvportgroup-12655                     Static      42
XXX_XX_00_x               dvportgroup-12664                     Static      128
XXX_XX_40_x               dvportgroup-12674                     Static      128
XXX_XX_60_x               dvportgroup-12680                     Static      128
XXX_XX_01_x               dvportgroup-12665                     Static      128
XXX_XX_14_x               dvportgroup-12673                     Static      128
XXX_XX_02_x               dvportgroup-12666                     Static      128
XXX_XX_13_x               dvportgroup-12672                     Static      128
XXX_XX_03_x               dvportgroup-12667                     Static      128
XXX_XX_12_x               dvportgroup-12671                     Static      128
XXX_XX_56_x               dvportgroup-12679                     Static      128
XXX_XX_04_x               dvportgroup-12668                     Static      128
XXX_XX_11_x               dvportgroup-12670                     Static      128
XXX_XX_57_x               dvportgroup-12678                     Static      128
dvSwitch1 All             dvportgroup-12661                     Static      128
XXX_XX_10_x               dvportgroup-12669                     Static      128
XXX_XX_54_x               dvportgroup-12677                     Static      128

The names and Ps have been changed to protect the innocents. Smiley Wink

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

On the portgroup the script finds all the available ports.

Then it checks all the VMs that have already a connection to that portgroup and removes that portkey from the list.

I keep the portkeys in a hash table because that makes it easy to remove entries.

$nicTypes = "VirtualE1000","VirtualE1000e","VirtualPCNet32","VirtualVmxnet","VirtualVmxnet2","VirtualVmxnet3" 
$ports
= @{}
$pgName = "MyPG"

#
Get all the portkeys on the portgroup
$pg
= Get-VirtualPortGroup -Distributed -Name $pgName
$pg
.ExtensionData.PortKeys | %{$ports.Add($_,$pg.Name)}

# Remove the portkeys in use
Get-View
$pg.ExtensionData.Vm | %{
   
$nic = $_.Config.Hardware.Device |
     
where {$nicTypes -contains $_.GetType().Name -and $_.Backing.GetType().Name -match "Distributed"}
   
$nic | %{$ports.Remove($_.Backing.Port.PortKey)}
}

# Assign the first free portkey
$key = ($ports.Keys | Sort-Object)[0]


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
10 Replies
LucD
Leadership
Leadership
Jump to solution

To change a connection to a dvSwitch you'll have to use the dvSwitch and the PortKey parameter only.

Get-vm $vmname | Get-NetworkAdapter | 
Set-NetworkAdapter -StartConnected $true -DistributedSwitch dvSwitch1 -PortKey 123 -Confirm:$false

The  only problem is to find the free portkeys on the dvSwitch portgroup :smileygrin:

Let me know if you need a routine for that ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

bgallagher72
Contributor
Contributor
Jump to solution

That helps.

If you have a routine to find the next open portkey that would be greatly helpful.

Reply
0 Kudos
bgallagher72
Contributor
Contributor
Jump to solution

Where does the netowrk name come into play? I have many portgroups on the one dvSwitch. How do I specify which one to use?

Reply
0 Kudos
bgallagher72
Contributor
Contributor
Jump to solution

That helps.

If you have a routine to find the next open portkey that would be greatly helpful.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

On the portgroup the script finds all the available ports.

Then it checks all the VMs that have already a connection to that portgroup and removes that portkey from the list.

I keep the portkeys in a hash table because that makes it easy to remove entries.

$nicTypes = "VirtualE1000","VirtualE1000e","VirtualPCNet32","VirtualVmxnet","VirtualVmxnet2","VirtualVmxnet3" 
$ports
= @{}
$pgName = "MyPG"

#
Get all the portkeys on the portgroup
$pg
= Get-VirtualPortGroup -Distributed -Name $pgName
$pg
.ExtensionData.PortKeys | %{$ports.Add($_,$pg.Name)}

# Remove the portkeys in use
Get-View
$pg.ExtensionData.Vm | %{
   
$nic = $_.Config.Hardware.Device |
     
where {$nicTypes -contains $_.GetType().Name -and $_.Backing.GetType().Name -match "Distributed"}
   
$nic | %{$ports.Remove($_.Backing.Port.PortKey)}
}

# Assign the first free portkey
$key = ($ports.Keys | Sort-Object)[0]


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
bgallagher72
Contributor
Contributor
Jump to solution

I get the following errors while trying to run this:

Exception calling "Remove" with "1" argument(s): "Key cannot be null.
Parameter name: key"
At \DeployFromTemplatetest.ps1:127 char:29
+             $nic | %{$ports.Remove <<<< ($_.Backing.Port.PortKey)}
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

Is this nrmal? Seems that it is still getting the next avaliable port number.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Although I don't understand why this can happen, you seem to have some NICs that are connected to a dvSwitch portgroup but that do not have a portkey. We can filter those out with a Where-clause.

See if this variation runs error-free

$nicTypes = "VirtualE1000","VirtualE1000e","VirtualPCNet32","VirtualVmxnet","VirtualVmxnet2","VirtualVmxnet3" 
$ports = @{}
$pgName = "MyPG"

# Get all the portkeys on the portgroup
$pg = Get-VirtualPortGroup -Distributed -Name $pgName
$pg.ExtensionData.PortKeys | %{$ports.Add($_,$pg.Name)}

# Remove the portkeys in use Get-View
$pg
.ExtensionData.Vm | %{
   
$nic = $_.Config.Hardware.Device |
     
where {$nicTypes -contains $_.GetType().Name -and $_.Backing.GetType().Name -match "Distributed"}
   
$nic | where {$_.Backing.Port.PortKey} | %{$ports.Remove($_.Backing.Port.PortKey)}
}

# Assign the first free portkey
$key
= ($ports.Keys | Sort-Object)[0]
$key


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
bgallagher72
Contributor
Contributor
Jump to solution

I am not sure whats going on but it looks like it is choosing the first used port. I ran it both ways and the port for $key is the first used one in the port group. So when I try and setup a VM using it I get port is in use. I am also getting a bunch of errors but it still give me a key. Is there anyway to find the first unused port and at leat suppress the errors?

PowerCLI > get-vm -Name test2008_14 | Get-NetworkAdapter | Set-NetworkAdapter -StartConn
ected $true -DistributedSwitch dvswitch1 -portkey 2055

Confirm
Are you sure you want to perform this action?
Performing operation "Setting StartConnected: True" on Target "Network adapter 1".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): y
Set-NetworkAdapter : 2/14/2012 8:33:21 AM    Set-NetworkAdapter        The specified port '2055' does not exists or it's not avai
lable for vnic connection.
At line:1 char:67
+ get-vm -Name test2008_14 | Get-NetworkAdapter | Set-NetworkAdapter <<<<  -StartConnected $true -DistributedSwitch dvswitch1 -po
rtkey 2055
    + CategoryInfo          : InvalidArgument: (:) [Set-NetworkAdapter], InvalidArgument
    + FullyQualifiedErrorId : Client20_VirtualNetworkServiceImpl_TryGetAvailableDVPortGroup_PortNotFound,VMware.VimAutomation.Vi
   Core.Cmdlets.Commands.VirtualDevice.SetNetworkAdapter

Hear is the errors that I get while running the script, multiple times.


C:\Users\XXXXXXXX\Documents\PowerCli\Deploy\DeployFromTemplate2.ps1:123 char:46
               where {$nicTypes -contains $_.GetType <<<< ().Name -and $_.Backing.GetType().Name -match "Distributed"}
   + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
   + FullyQualifiedErrorId : InvokeMethodOnNull

The part of the script I am using to connect the VM to the DVS.

     #Get Free DVS port
        $nicTypes = "VirtualE100","VirtualE100e","VirtualPCNet32","VirtualVmxnet","VirtualVmxnet2","VirtualVmxnet3"
        $ports = @{}
        $pgName = "XXX_XX_57_x"

        # Get all the portkeys on the portgroup 
        $pg = Get-VirtualPortGroup -Distributed -Name $pgName
        $pg.ExtensionData.PortKeys | %{$ports.Add($_,$pg.Name)}

        # Remove the portkeys in use  Get-View
        $pg.ExtensionData.Vm | %{
            $nic = $_.Config.Hardware.Device |
              where {$nicTypes -contains $_.GetType().Name -and $_.Backing.GetType().Name -match "Distributed"}
            $nic | where {$_.Backing.Port.PortKey} | %{$ports.Remove($_.Backing.Port.PortKey)}
        }

        # Assign the first free portkey
        $key = ($ports.Keys | Sort-Object)[0]
        $key
    #Connect to DVS
    $VMStatus = GET-VM $vmname | Get-NetworkAdapter
    if (!(($VMStatus.NetworkName -eq $vlan) -and (($VMStatus.ConnectionState).StartConnected -eq "False")))
        {
            Get-VM -Name $vmname | Get-NetworkAdapter | Set-NetworkAdapter -StartConnected $true `
                -DistributedSwitch dvSwitch1 -PortKey $key -Confirm:$false
            Get-VM -Name $vmname
        }

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Looks like my nictypes where missing a zero in the "VirtualE1000" and "VirtualE1000e" types.

Did you have NIC of that type ?

If yes, can you try again ? I updated the scripts above.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

bgallagher72
Contributor
Contributor
Jump to solution

Awesome, the first script worked.

Thanks so much for your help!

Reply
0 Kudos