dvSwitch scripting – Part 1 – Creation

With the introduction of vSphere one of the new features that was introduced was the vNetwork Distributed Switch. This new type of switch offers many more features than the “classical” vSwitch we knew.

In the current PowerCLI build there are no cmdlets present to create, configure, manage and remove this new type of switch. Surely this will change in one of the upcoming PowerCLI releases.

To bridge the time till the next release, I decided to write a number of functions that would allow PowerCLI users to work with the vNetwork Distributed Switch.This first part of my dvSwitch series will show the functions that:

  • create a dvSwitch
  • find out which hosts can be connected to the dvSwitch
  • and connect the hosts to the dvSwitch

All the functions will be minimalistic, that means that only the essential configuration parameters will be defined. Most of the other configuration parameters will follow later on.

The script creates a dvSwitch, named dvSw1, in the Network folder under a datacenter, named Home1. The dvSwitch will be configured with 2 uplinks. The basename of each uplink is dvUpl.

function New-dvSwitch{
param($dcName, $dvSwName, $baseUplink, $nrUplink)

$dc = Get-View -ViewType Datacenter -Filter @{"Name"=$dcName}
$net = Get-View -Id $dc.NetworkFolder
$spec = New-Object VMware.Vim.DVSCreateSpec
$spec.configSpec = New-Object VMware.Vim.DVSConfigSpec
$spec.configspec.name = $dvSwName
$spec.configspec.uplinkPortPolicy = New-Object VMware.Vim.DVSNameArrayUplinkPortPolicy

$spec.configspec.uplinkPortPolicy.UplinkPortName = (1..$nrUplink | % {$baseUplink + $_})

$taskMoRef = $net.CreateDVS_Task($spec)

$task = Get-View $taskMoRef
while("running","queued" -contains $task.Info.State){
function Get-dvSwHostCandidate{
param($container, $recursive, $dvs)

$dvSwMgr.QueryCompatibleHostForExistingDvs($dc.MoRef, $true, $dvs)

function Add-dvSwHost{
param($dvSwitch, $hostMoRef, $pnic, $nrUplink)

$spec = New-Object VMware.Vim.DVSConfigSpec
$tgthost = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberConfigSpec
$tgthost.operation = "add"
$tgthost.backing = New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicBacking
0..($nrUplink - 1) | % {
$tgthost.Backing.PnicSpec += New-Object VMware.Vim.DistributedVirtualSwitchHostMemberPnicSpec
$tgthost.Backing.PnicSpec[$_].pnicDevice = $pnic[$_]
$tgthost.host = $hostMoRef
$spec.Host = $tgthost
$spec.ConfigVersion = $dvSwitch.Config.ConfigVersion

$taskMoRef = $dvSwitch.ReconfigureDvs_Task($spec)
$task = Get-View $taskMoRef
while("running","queued" -contains $task.Info.State){

$datacenterName = "Home1"
$dvSwitchName = "dvSw1"
$dvSwitchUplinkBasename = "dvUp1"
$dvSwitchUplinkNumber = 2

$dvSwMgr = Get-View (Get-View ServiceInstance).content.dvSwitchManager

$dvSwMoRef = New-dvSwitch $datacenterName $dvSwitchName $dvSwitchUplinkBasename $dvSwitchUplinkNumber
$dvSw = Get-View -Id $dvSwMoRef

$dc = Get-Datacenter $datacenterName | Get-View
$candidates = Get-dvSwHostCandidate $dc.MoRef $true $dvSwMoRef
$candidates | % {
$esx = Get-View $_
if($esx.runtime.connectionState -eq "connected"){
$pnicInUse = @()
foreach($vswitch in $esx.Config.Network.Vswitch ){
foreach($pnic in $vswitch.pnic){
$pnicInUse += $pnic
foreach($vswitch in $esx.Config.Network.ProxySwitch ){
foreach($pnic in $vswitch.pnic){
$pnicInUse += $pnic

$pnicFree = @()
foreach($pnic in $esx.Config.Network.Pnic){
if(!($pnicInUse -contains $pnic.Key)){
$pnicFree += $pnic.Device
if($pnicFree.Count -ge $dvSwitchUplinkNumber){
Add-dvSwHost $dvSw $esx.MoRef $pnicFree $dvSwitchUplinkNumber

Some annotations:
Line 49-52: define the peculiarities of the dvSwitch
Line 5: dvSwitches have to be created in the Network folder under a datacenter
Line 34-37: the first $nrUplink free physical NICs of an ESX host are used to connect to the dvSwitch’s uplinks
Line 40: refresh the dvSwitch object
Line 41: use the same configuration version as can be found in the dvSwitch object
Line 61-82: a rather straight-forward algorithm to look up the available pNICs of an ESX server. The array $pnicFree contains all the free pNICs on the specific ESX server.
Line 83: if there are sufficient free pNICs available to connect to the dvSwitch’s uplinks the ESX host is added to the dvSwitch.

In the next parts of this series I’ll show how to configure and use the dvSwitch. As a preview have a look at Arne’s article called PowerCLI: Set-dvSwitch.

Update: there have been quite a few excellent dvSwitch related posts lately. A selection:

vNetwork Distributed Switch – a demo to explain it all from Guy Brunsdon

vSphere DvSwitch caveats and best practices! from Eric Sloof

vNetwork Distributed Switches (vDS) an overview from Barry Coombs

vSphere 4.0 vNetwork Distributed Switch (vDS) – Video Demonstration + Architecture Diagram from Hany Michael

dvSwitch? from Duncan Epping

PowerCLI: Set-dvSwitch from Arne Fokkema

VMware vSphere vDS, VMkernel Ports, and Jumbo Frames from Scott Lowe

09. October 2009 by LucD
Categories: dvSwitch, PowerCLI, PowerShell, vSphere | Tags: , , , | 23 comments

Comments (23)

  1. can anyone share me the perl script to add host to the dvs? Thank you!

  2. Pingback: Automate Migrating ESX Host Interfaces to Nexus 1000V - WKSB Solutions

  3. Hi LucD,
    Great script

    Is there any way to change the “dvSwitch Uplink Group Name” when this is created via PowerCLI as this is referenced in an imported profile and the names need to match. The last part of the name is generated dynamically i.e. dvSwitch-DVUplinks-.


  4. Hi Luc,

    Any luck with the Nexus dVs ??

  5. Hi Luc,

    I’ve tried to use your scripts on a Nexus vDs with no luck, do you know of anyone that has created a script to add a host to a Nexus dVs ?? If you like a challange to do what appears no one has done i can provide you the Onyx dump.
    Hope to hear from you soon



    • Hi Rob, I must admit I haven’t tried to automate the use of a Nexus vDs myself yet.
      But it looks an interesting challenge.
      I’ll play around a bit in my lab.

  6. Hi Luc,

    It works perfectly. Thanks for the prompt response as always.

  7. Hi Luc,

    I’ve played around some more and there seems to be an issue with the names of the free nics. I have three nics to begin with (vmnic1, 2 and 3) and when I run the script the first time, it creates a dvSwitch, adds the ESX hosts and allocates vmnic1.

    When I check the pnicInUse and pnicFree variables it lists vmnic0 as in use and vmnic1, 2 and 3 as free. I would expect this as when the function runs the first time, those cards would be free.

    However when I run the script again with a new dvSwitch name, I get an error when adding the ESX hosts as it is trying to add vmnic1 to the new switch even though it has already been allocatd to the previous switch.

    Am I missing something really basic here, or is there a function to have the vmnics in use rescanned in order to update the pnicInuse variable?

    • Hi Alasdair, there was indeed a bug in the script.
      Where I determined which pNics were in use, I only looked at the classic vSwitches but not at the dvSwitches. The script has been updated (lines 71-75 were added).
      Now it should work as designed.
      Thanks for finding this “feature”.

  8. Hi Luc,

    I’m using your script to try and create two dvSwitches. The first gets created no problem, but when change the values in lines 50 – 53 and run the script from line 50, the dvSwitch gets created but is not added to any of my hosts.

    The error suggests that it is trying to allocate vmnic1 to the second switch on each host, but that nic was already allocated to the first switch.

    How can I refresh the pnicFree value so that when I run the script again it picks up that the next available vmnic has changed?

    Thanks for any help.

  9. Hi Luc,

    Yes I did, but it still put that bit of html code in a funny place. I’ve removed it and now as always your script runs like a dream. Thanks for all your hard work on this, it has saved me a lot of time and hassle.

    Best regards….

  10. Hi Luc,

    When I run the script I get the following error

    Missing ‘in’ after variable in foreach loop.
    At :line:81 char:14
    + foreach($pnic& <<<< nbsp; in $esx.Config.Network.Pnic){

    Any ideas?

    • Hi Alasdair,
      Something must have gone wrong during the copy/paste of the source.
      That line should read: foreach($pnic in $esx.Config.Network.Pnic){

      Did you use the “copy to clipboard” button at the top of the script block ?

      Copy to clipboard

  11. Hi Luc,

    Thanks for these dvswitch scripts.

    I’m not that experenced with scripting and was wondering if you could help me.

    How can i change your first script to not add a new dvswitch but like your other scripts “get-dvswitch” then do the “”Get-dvSwHostCandidate” then add the hosts to the vswitch.

    I’d like to use the first script to add a new host to an existing dvswitch.



    • Thanks Robert.
      You can copy the Get-dvSwitch function that is listed in Part 2 of the dvSwitch series.
      That function will return a DistributedVirtualSwitch object which you can use to pass to the Add-dvSwHost function as the first parameter.
      Something like this:

      $dvSw = Get-dvSwitch $datacenterName $dvSwitchName
      Add-dvSwHost $dvSw $esx.MoRef $pnicFree $dvSwitchUplinkNumber

  12. Hi LucD,

    Thanks for you help, i have a total of 6 esx servers, each one with 4 nics, vmnic0 is already connect to vSwitch0, so free to use i have 3, but only 2 defined in the number of uplinks, your script correctly chooses vmnic1 and 2, but it only adds the first esx. In my lab i have 3 Vcenters and 2 esx per vcenter, and the script has the same behavior in all of them. 🙁

    • Vitor, found the cause of the problem. The ConfigVersion of the dvSwitch (line 41) that was in the $dvSwitch variable didn’t get refreshed. That’s what the UpdateViewData method in line 40 now does.
      After the addition of the 1st ESX server, the ConfigVersion is incremented.
      The copy of the ConfigVersion in the PS variable doesn’t get refreshed automatically.
      Thanks for finding this bug.

  13. Hi,

    I getting the following error when i have 2 esx servers on vcenter, with one its ok.

    Reconfigure vNetwork Distributed Switch LABDVS A specified parameter was not correct. spec.confi-figVersion

    • As you can see from the screenshot in Part 2 I also ran the script against a vCenter with 2 ESX servers.
      It worked for me.
      I’ll see if I can reproduce your problem.

  14. Pingback: VMware vSphere - ????????????? ??? » ??? ????? ? ??? ???????? vSphere 4.0 vSphere 4.0 vNetwork Distributed Switch (vDS).

  15. Pingback: vSphere 4.0 vNetwork Distributed Switch (vDS) - Video Demonstration + Architecture Diagram | The deep core of the phenomena| HyperViZor

  16. Pingback: Tweets that mention LucD notes » dvSwitch scripting – Part 1 – Creation -- Topsy.com

Leave a Reply

Required fields are marked *