Home > dvSwitch, PowerCLI, PowerShell, vSphere > dvSwitch scripting – Part 6 – Private VLAN

dvSwitch scripting – Part 6 – Private VLAN

January 29th, 2010 Leave a comment Go to comments

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:

  1. Create the PVLANs on the dvSwitch
  2. 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 -Filter @{“Name”=”MVV30010″} | %{
Get-View -ViewType VirtualMachine | %{
if($_.Config.Hardware.Device | where{$_.gettype().Name -eq “VirtualSerialPort”}){
$_.Name
}
}