dvSwitch scripting – Part 6 – Private VLAN
Another post in the dvSwitch series. This time I’ll tackle the creation and use of a private VLANs (PVLAN) on a dvSwitch.
For those that are not that familiar with PVLANs have a look at KB1010691, that article gives a good overview of the PVLAN concept. And there were several sessions during the last VMworld that talked about PVLANs. The most noteworthy being TA2525 VMware vSphere 4 Networking Deep Dive.
In short, PVLANs allows isolation for guests on a shared IP subnet.
To use PVLANs on a dvSwitch we need to execute a two-step process:
- Create the PVLANs on the dvSwitch
- Assign a PVLAN to a Portgroup
The start configuration is a regular dvSwitch which has three portgroups defined.
The dvSwitch has no PVLANs defined.
PVLAN creation
function Get-dvSwitch{
param($dcName,$dvSwName)
$dcNetFolder = Get-View (Get-Datacenter $dcName | Get-View).NetworkFolder
$found = $null
foreach($net in $dcNetFolder.ChildEntity){
if($net.Type -eq "VmwareDistributedVirtualSwitch"){
$temp = Get-View $net
if($temp.Name -eq $dvSwName){
$found = $temp
}
}
}
$found
}
function New-dvSwPVLAN{
param($dvSw, $primaryNr, [int[]] $secondaryNr, [string[]] $secondaryType)
$spec = New-Object VMware.Vim.VMwareDVSConfigSpec
# Primary
$pvlan = New-Object VMware.Vim.VMwareDVSPvlanConfigSpec
$pvlan.operation = "add"
$pvlan.pvlanEntry = New-Object VMware.Vim.VMwareDVSPvlanMapEntry
$pvlan.pvlanEntry.primaryVlanId = $primaryNr
$pvlan.pvlanEntry.pvlanType = "promiscuous"
$pvlan.pvlanEntry.secondaryVlanId = $primaryNr
$spec.PvlanConfigSpec += $pvlan
# Secondaries
for($i = 0;$i -lt $secondaryNr.Count; $i++){
$pvlan = New-Object VMware.Vim.VMwareDVSPvlanConfigSpec
$pvlan.operation = "add"
$pvlan.pvlanEntry = New-Object VMware.Vim.VMwareDVSPvlanMapEntry
$pvlan.pvlanEntry.primaryVlanId = $primaryNr
$pvlan.pvlanEntry.pvlanType = $secondaryType[$i].ToLower()
$pvlan.pvlanEntry.secondaryVlanId = $secondaryNr[$i]
$spec.PvlanConfigSpec += $pvlan
}
$dvSw.UpdateViewData()
$spec.ConfigVersion = $dvSw.Config.ConfigVersion
$taskMoRef = $dvSw.ReconfigureDvs_Task($spec)
$task = Get-View $taskMoRef
while("running","queued" -contains $task.Info.State){
$task.UpdateViewData("Info")
}
}
$datacenterName = "Home1"
$dvSwitchName = "dvSw1"
$dvSw = Get-dvSwitch $datacenterName $dvSwitchName
New-dvSwPVLAN $dvSw 2 102,202 "community","isolated"
Annotations
Line 1-15: The Get-dvSwitch function was already discussed in Part 2 of the dvSwitch series.
Line 18: The parameters $secondayNr and $secondaryType are defined as arrays. That way the function can handle the creation of multiple secondary PVLANs in one call.
Line 37: The PVLAN typenames are case sensitive! To avoid errors, the script converts the passed typenames to lowercase. Just to make sure
Line 42-43: As with any dvSwitch method, it’s important to pass the correct ConfigVersion. Otherwise you get a message saying “Cannot complete operation due to concurrent modification by another operation“.
Line 57: This sample call creates a Primary PVLAN with VLAN Id 2, a Secondary PVLAN of type Community with VLAN Id 102 and another Secondary PVLAN of type Isolated with VLAN Id 202.
Portgroup assignment
function Get-dvSwitch{
param($dcName,$dvSwName)
$dcNetFolder = Get-View (Get-Datacenter $dcName | Get-View).NetworkFolder
$found = $null
foreach($net in $dcNetFolder.ChildEntity){
if($net.Type -eq "VmwareDistributedVirtualSwitch"){
$temp = Get-View $net
if($temp.Name -eq $dvSwName){
$found = $temp
}
}
}
$found
}
function Set-dVSwPgPVLAN{
param($dvSw, $dvPgName, $pvlanNr)
# Find the portgroup
$dvSw.Portgroup | % {
$dvPgTemp = Get-View -Id $_
if($dvPgTemp.Name -eq $dvPgName){
$dvPg = $dvPgTemp
}
}
$spec = New-Object VMware.Vim.DVPortgroupConfigSpec
$spec.defaultPortConfig = New-Object VMware.Vim.VMwareDVSPortSetting
$spec.defaultPortConfig.vlan = New-Object VMware.Vim.VmwareDistributedVirtualSwitchPvlanSpec
$spec.defaultPortConfig.vlan.pvlanId = $pvlanNr
$dvPg.UpdateViewData()
$spec.ConfigVersion = $dvPg.Config.ConfigVersion
$taskMoRef = $dvPg.ReconfigureDVPortgroup_Task($spec)
$task = Get-View $taskMoRef
while("running","queued" -contains $task.Info.State){
$task.UpdateViewData("Info")
}
}
$datacenterName = "Home1"
$dvSwitchName = "dvSw1"
$dvSw = Get-dvSwitch $datacenterName $dvSwitchName
Set-dvSwPgPVLAN $dvSw "dvPG1" 2
Set-dvSwPgPVLAN $dvSw "dvPG2" 102
Set-dvSwPgPVLAN $dvSw "dvPG3" 202
Annotations
Line 1-15: The Get-dvSwitch function was already discussed in Part 2 of the dvSwitch series.
Line 20-26: The scripts looks for the DistributedVirtualPortgroup object in order to pass the correct ConfigVersion (see line 34).
Line 49-51: The call to the dvSwPgPVLAN requires you to pass the portgroupname and Secondary PVLAN Id.
The final result, the three portgroups have now each been assigned to a PVLAN.
Get-View -ViewType VirtualMachine | %{
if($_.Config.Hardware.Device | where{$_.gettype().Name -eq “VirtualSerialPort”}){
$_.Name
}
}




