dvSwitch scripting – Part 2 – dvPortgroup

In Part 1 of the dvSwitch scripting series I created a simple dvSwitch with 2 uplinks, which I connected to all the ESX hosts that were returned as possible candidates. In this part I will show you how to add a dvPortgroups and how you can connect Virtual Machines to this dvPortgroup.

This is the schematic of what we have so far.


And the uplink port allocation.


Update March 28th 2010

The previous version of the New-dvSwPortgroup function was rather simplistic.

This new, and completely re-vamped, version allows you to specify the VLAN type and the VLANIds if required. Note that the new version requires PowerShell v2 RTM.

Update July 22nd 2010

With this new version all the security and teaming options are available. Follow the hyperlinks for more information on the different parameters.

Update July 15th 2011

The Get-dvSwitch function will now also search all the subfolders of the Network Folder.

There are a number of options that you can’t configure from the vSphere client! For example the load based teaming as described in Frank Denneman’s blog.

The following table shows the available parameters. The new ones are highighted.

Parameter Type Default Comment
PgNumberPorts int 64
PgBinding string earlyBinding
PgVLANType string
PgVLANId int[]
SecPolPromiciousMode Boolean false
SecPolMacChanges Boolean true
SecPolForgedTransmits Boolean true
TeamingCheckDuplex Boolean false
TeamingCheckErrorPercent Boolean false
TeamingPercentage int
TeamingCheckSpeed Boolean false
TeamingSpeed int
TeamingPolicy string loadbalance_srcid Accepted values:loadbalance_iploadbalance_srcmac




TeamingNotifySwitches Boolean true
TeamingRollingOrder Boolean false
TeamingReversePolicy Boolean true
TeamingActiveUplink string[]
TeamingStandbyUplink string[]


Line 1: The function Get-dvSwitch loops through all the children of the Network folder to find the dvSwitch that was requested. If the dvSwitch is not found, the function returns $null.

Line 5-24: This local function allows to recursively search through all the folders under the Network Folder.

Line 29-55: The helper function Get-VLANRanges takes an array of VLAN Ids and converts them to the minimal number of NumericRange objects. The function returns an array with the resulting NumericRange objects.

Line 58-78: The New-dvSwPortgroup parameters. Note that several of the parameters have default values. Also note that the function has two positional parameters and that the other parameters are all named parameters. Have a look at the Example calls of the function a bit further along.

Line 80: To allow the function to be used in a pipeline, the new version uses the Process block.

Line 144: the AddDVPortgroup_Task requires the portgroup Type to be specified, allthough the SDK reference says otherwise in the description of the DVPortgroupConfigSpec object. The accepted values can be found in the DistributedVirtualPortgroupPortgroupType enumeration. The possible values are:

  • earlyBinding: free port assigned when the VM is configured to connect to the dvPortgroup
  • ephemeral: free port assigned when VM is powered on and removed when the VM is powered off
  • lateBinding: free port assigned when VM is powered on

These values correspond with what you see under Port binding in the vSphere client.


Line 92-106: The part where the VLAN type of the the new portgroup is configured. Possible values here are:

  • None: the portgroup does not use a VLAN
  • VLAN: the portgroup uses a single VLAN Id
  • VLAN Trunking: the portgroup uses trunk mode.The guest OS manages its own VLAN tags.
  • Private VLAN: the portgroup uses a private VLAN Id. The dvSwitch needs to have primary and secondary VLANIds defined and you select the desired secondary PVLANId for this mode.

These values correspond with what you see under VLAN type in the vSphere client when you create a new Distributed Virtual Port Group .

Line 108-114: The part where the security settings are defined.
Line 116-142: The Teaming and failover settings.


Some sample calls of the New-dvSwPortgroup function.


Line 8: Straightforward call, creates a new portgroup taking all the defaults

Line 9: The dvSw is passed through the pipeline to the New-dvSwPortgroup function. Again taking all the defaults.

Line 10: The number of ports is passed to the call.

Line 11-13: These show the possible values for the portgroup type, the PgBinding parameter.

Line 16: Creates a portgroup that uses a single VLAN Id

Line 19-20: Two examples how a portgroup with Trunking VLAN can be created. This shows the usefulness of the Get-VLANRanges helper function. In the vSphere Client you’ll see that a minimal number of ranges was used.

Line 23: A portgroup with a Private VLAN.

Line 26: Create a portgroup with the Security option MAC Address Changes set to Reject.

Line 29: A portgroup with Load Balancing based on the originating virtual port (the default)  and with 2 active uplinks.

Portgroup dvPg8

Portgroup dvPg9

Line 23: The final sample call shows how to create a portgroup that uses a Private VLAN. See also dvSwitch scripting – Part 6 – Private VLAN for the concept behind private VLANs.

The secondary VLANId on the Distributed Virtual Switch

The portgroup dvPg10

Now that there is a dvPortgroup, we can configure a VM to connect to the dvPortgroup.


Line 30: the Device property in the VirtualDeviceConfigSpec object needs to have an object of a type that corresponds with the network card type you are trying to move to the dvPortgroup.

Line 43: Since this requires the ReconfigVM_Task method, which is executed on a VirtualMachine object, you can only migrate one guest per call. You can migrate multiple NICs of the guest in one call to ReconfigVM_Task. To do this you will have to create an array of VirtualDeviceConfigSpec objects. Each array element corresponding with 1 NIC.

Note that this function already appeared in a slightly different format on Arne’s blog. See the PowerCLI: Set-dvSwitch entry.

Schematically we now have something like this.


This concludes Part2 of the dvSwitch series.


    Raymundo Escobar

    Hi LUC, this save me the ass and I have to post a BIG thanks!!!


    Thank as as always for your excellent work. I’ve been experimenting with your code in my LAB and I get a Null error when executing

    $dvSw.Portgroup | %{Get-View -Id $_}

    I tracked it down and found out when I enter Datacenters that have spaces in them that is when the error occurs. How do I deal with Datacenters that have spaces in them?

    $DatacenterName = “DataCenter 1”
    $OlddvSwitch = “DVS-Net1”

    function Get-dvSwitch{

    param([parameter(Position = 0, Mandatory = $true)][string]$DatacenterName,
    [parameter(Position = 1, Mandatory = $true)][string]$dvSwitchName)


      Hi Andre,
      I’m not sure how you called the function, but when I use single quotes and named parameters, it seems to work for me.
      See this short, abstract example

      function Test-Function{
      param([parameter(Position = 0, Mandatory = $true)][string]$DatacenterName,
      [parameter(Position = 1, Mandatory = $true)][string]$dvSwitchName)

      Get-Datacenter -Name $DatacenterName

      $dcName = 'DC 1'
      Test-Function -DatacenterName $dcName -dvSwitchName 'dvSw1'


    Hi all,

    I used Onyx to debug what the client sent to server;

    I get SOAP message;

    I copy it anh use another to sent to server (pass authenticate) but it have an error

    Array ( [faultcode] => ServerFaultCode [faultstring] => Unable to find specified dynamic type VirtualEthernetCardDistributedVirtualPortBackingInfo while parsing serialized DataObject of type vim.vm.device.VirtualDevice.BackingInfo at line 15, column 12 while parsing property “backing” of static type VirtualDeviceBackingInfo while parsing serialized DataObject of type vim.vm.device.VirtualE1000 at line 9, column 10 while parsing property “device” of static type VirtualDevice while parsing serialized DataObject of type vim.vm.device.VirtualDeviceSpec at line 7, column 8 while parsing property “deviceChange” of static type ArrayOfVirtualDeviceConfigSpec while parsing serialized DataObject of type vim.vm.ConfigSpec at line 5, column 6 while parsing call information for method ReconfigVM_Task at line 3, column 4 while parsing SOAP body at line 2, column 2 while parsing SOAP envelope at line 1, column 0 while parsing HTTP request for method reconfigure on object of type vim.VirtualMachine at line 1, column 0 [detail] => Array ( [InvalidRequestFault] => ) )

    pls tell me how; how Vsphere client can sent


      @aihx, I see.
      I’m afraid I don’t know how to talk to vSphere through raw SOAP packages.
      Perhaps you could raise your question in the VMware Developer community.


    HI LucD

    I use vSphere Client and Onyx to get XML

    b2 57 13 50 92 89 c3 d5-d4 23 15 6d 9f fb 34 7b
    VM Network

    I use PHP with SOAP to send XML to vmware; but get this error

    when you use java or .net it also create a xml and send to vmware (call API)

    i use vm 5


    Unable to find specified dynamic type VirtualEthernetCardDistributedVirtualPortBackingInfo

    I get this error; I do not know what happen whith VW; I only send XML to WSDL


      @aihx, you are saying that

      New-Object VMware.Vim.VirtualEthernetCardDistributedVirtualPortBackingInfo

      doesn’t work for you and that it returns an error ?
      Which PowerCLI version are you using ? Do a



    Just thought I’d post to say a big THANK YOU!. These scripts are amazing and have saved me sooo much time. I don’t understand why vmware didn’t add this functionality into PowerCLI

    You certainly know your stuff

    Good work!



      Thanks Tom, much appreciated.
      There is since a couple of days a fling available that provides dvSwitch cmdlets.
      Have a look at the vSphere Distributed Switch PowerCLI cmdlets blog post.



    Well, i got a test1.ps1 file with all the functions included from you dvportgroup post PLUS these lines at the end:
    $datacenterName = “Training”
    $dvSwitchName = “vDS-Production”
    $dvPgNumPorts = 128
    $dvSw = Get-dvSwitch -DatacenterName $datacenterName -dvSwitchName $dvSwitchName
    $dvSwPg = New-dvSwPortgroup $dvSw “dvPg1”

    Once executed i got this:


    I’m trying to create a new PG, but I’m getting this error. I’m using single ps1 file that includes all the above functions and some variables and the command.

    When I connect to the vcenter with powercli and start the ps1 file this is what I get:

    Unable to find type [parameter(Position = 0, Mandatory = $true)]: make sure that the assembly containing this type i
    At C:\trouble\vdsportgroup.ps1:2 char:53
    + param([parameter(Position = 0, Mandatory = $true)][ <<<< string]$DatacenterName,

    Any idea what I'm doing worng?
    Thanks! I'm using powercli 4.1, vcenter 4.1, esx 4.0 btw


      @bali, I assume you are trying to do a call to the Get-dvSwitch function ?
      The first parameter must be a string containing the name of the Datacenter where the dvSwitch is located.
      You can’t use the Datacenter object as is returned by Get-Datacenter.
      Perhaps you can include some of the lines from your script ?


    Hi Luc,

    I think I’m closer 🙂

    But I get the error

    New-dvSwPortgroup : Cannot bind argument to parameter ‘dvSw’ because it is null
    I set, $datacenterName, $dvSwitchName, $dvPgNumPorts,

    regards, Sven


      @Sven, the scripts can not be run as .ps1 files as such.
      The code contains functions, Get-dvSwitch and New-dvSwPortgroup, which you can call in your script. There are 2 ways of doing this in practice.
      1) You save my code in a .ps1 file and in your script you first dot-source that .ps1 file and then you call the functions.

      2) You copy and paste my code into your script and at the end you call the functions

      Example 1: the functions are saved in file.ps1.
      In your script you do (note the blank between the 2 dots!)

      . .\file.ps1
      $dvSw = Get-dvSwitch -DatacenterName $datacenterName -dvSwitchName

      Example 2: everything in 1 .ps1 file

      function Get-dvSwitch{
      function Get-VLANRanges{
      function New-dvSwPortgroup{

      $dvSw = Get-dvSwitch -DatacenterName $datacenterName -dvSwitchName

      I hope this helps.


    Hi Luc,

    this scripts looks like what I need. But sorry for this dummy question. How can I ran this script as command? Save the script (140 lines) to a ps1 file and run with example “.\New-dvSwPortgroup dvSwitch04-1 “MyTestName” -PgNumberPorts 126 -PgVLANType “VLAN” -PgVLANId 33″

    regards, Sven

    Jay Jahns

    @LucD It’s more or less a PERL problem, but for the most part, I’ve ported what you got over to that and I’m having hash arguments not valid and so on. The NumericRange is not supposed to be hashed is it?

    Jay Jahns

    Do you know how to port this to the Perl SDK? I know this is old and all, but the NumericRange aspect for the vlan trunking is not working for me.


      @Jay. What exactly is the problem ? I assume you mean the vlanId property ? That is an array of NumericRange objects. And each NumericRange object has a Start and End property, both of which hold integer values representing vlanIds. The valid numbers are between 0 and 4094.



    great script!

    but one thing:
    in the function New-dvSwPortgroup you use at line 63 the variable “[switch]$TeamingNotifySwitches = $true”, but at line 120 you use “$NotifySwitches”. I think that’s a mistake.



      @Martin, well spotted. That was indeed a typo. It’s corrected now.


    Wow… are you from this planet ? Thanks !!


    Hi Luc…

    I’ve been trying to get some experience with PowerShell\PowerCLI and your posts helped me a lot… thank you !

    I was just wondering if it would be possible to add some other properties to your New-dvSwPortgroup function, specifically… I am looking to change the default value “Mac Address Change : Accept” to Reject…

    Thanks in advance,


      Hi Pablo, the script has been updated.
      It now has support for the security policy and for the teaming policy.
      14 new parameters available !

    gert van gorp

    Hi Luc,

    Nice script you make. I am trying to refine your script to change to connect a vm to a dvportgroup.

    I have a NIC with a static mac address, but when I use the script it changes to a dynamic address.

    I found VMware.Vim.VirtualDeviceConnectInfo but I cannot get it to work.

    can you get me started?



      Thanks Gert.
      As it happens I’m nearly done with the creation of 2 new dvSwitch related functions that will offer the Get-NetworkAdapter and Set-NetworkAdapter functionality for dvSwitch based portgroups.


      The two functions I mentioned earlier are now posted in dvSwitch scripting – Part 8 – Get and Set network adapters. Have a look if this is what you meant.

    gert van gorp


    Maybe you can help me..

    I am looking for a way to check if a dvp with a certain VLAN exists. Do you have any idea how to do this?

    I am creating a sort of class setup with for each workspot a seperate vlan, connected on a distributed portgroup

    thanks in advance.




      Hi Gert,
      Yes that’s possible.
      I’ll get back to you with a script to do that. Might even do a new post on it.


        Gert, you can find a script to do this in dvSwitch scripting – Part 7 – Find portgroup/Change VLAN Id.


    Wow, Luc you are a genius! This and part 1 was exactly what I needed, didn’t have to modify anything!

    One thing though, I have a requirement to create VMkernel ports for VMotion on the dvSwitches… do you have any idea how I can do that? or do i just need to wait a bit longer for part 3? 🙂

    Keep up the great work!


      Thanks Mark.
      The next part should be published in the coming days.

Leave a Reply

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.