Hyper-V How To: Modify VLAN Settings using Script

Some friends here on the Hyper-V team shared a PowerShell 2.0 script for modifying hte VLAN settings on your VMs:

# Modify VLAN setting for VM

    $vmName = $(throw "Must supply a virtual machine name"),
    $vlanId = $(throw "Must supply  vlan id"),
    $computer = "."

$ns = "root\virtualization"

# get the computer system
$vm = gwmi -namespace $ns -computerName $computer Msvm_ComputerSystem -filter "ElementName = '$vmName'"

if ($vm -eq $null)
   "No virtual machine with name '$vmName'"

# get its related vssd
$vssd = gwmi -namespace $ns -computerName $computer -query "associators of {$vm} where AssocClass=Msvm_SettingsDefineState"

# get its synthetic and enumlated NICs
$nics = gwmi -namespace $ns -computerName $computer -query "associators of {$vssd} where AssocClass=Msvm_VirtualSystemSettingDataComponent" |
    where {$_.ResourceType -eq 10 -and ($_.ResourceSubType -eq 'Microsoft Synthetic Ethernet Port' -or
                                        $_.ResourceSubType -eq 'Microsoft Emulated Ethernet Port')}

if ($nics -eq $null)
   # vm does not have any NICs.
   "Virtual machine '$vmName' does not have any NICs"

# Find the first nic which has a connection
$nic = $nics | where {$_.Connection -ne $null} | select-object -first 1

if ($nic -eq $null)
    "None of the NICs on virtual machine '$vmName' are connected"

# get the connected switch port.
$connectedPort = [wmi]$nic.Connection[0]

# need to set the external trunk list of the external port on this same switch
# to include this vlan id, else traffic won't get through.

# first get its switch.
$switch = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_HostedAccessPoint"

# enumerate all of its ports. First the port which is externally connected.
$ports = gwmi -namespace $ns -computerName $computer -query "associators of {$switch} where ResultClass=Msvm_SwitchPort"
$externalPort = $null

foreach ($p in $ports)
   $switchLanEndpoint = gwmi -namespace $ns -computerName $computer -query "associators of {$p} where ResultClass=Msvm_SwitchLanEndpoint"
   if ($switchLanEndpoint -ne $null)
      $externalEthernetPort = gwmi -namespace $ns -computerName $computer -query "associators of {$switchLanEndpoint} where resultclass=Msvm_ExternalEthernetPort"
      if ($externalEthernetPort -ne $null)
         # we got it, we found the switch port connected to the external
         # port, save it and break out of the loop.
         $externalPort = $p

if ($externalPort -ne $null)
     # get the port's VlanEndpoint
     $vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$externalPort} where AssocClass=Msvm_BindsTo"
     # get the vlan's setting object
     $vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"

     # get the current trunk list and add the new vlan id into it.
     # one thing additionally we could do here, which the Hyper-V UI does is clean up
     # the old AccessVlan id of the port from the trunk list. But, we can't just remove the
     # old AccessVlan from the trunklist, because another port might be using the same vlan id.
     # We would have to enumerate all of the ports on the switch and build a new trunk list.
     # For the purposes of this script, don't worry about cleaning up old vlan id' from the trunk list.
     $trunkList = $vlanSetting.TrunkedVLANList
     if ($trunkList -notcontains $vlanid)
        $trunkList = $trunkList + $vlanId
        $vlanSetting.TrunkedVLANList = $trunkList
        $result = $vlanSetting.Put()
     # set the vlan mode into trunking mode.
     if ($vlan.DesiredEndpointMode -ne 5)
        $vlan.DesiredEndpointMode = 5
        $result = $vlan.Put()

# Now that we have finished with the trunklist, set the vlan id of the original connected port.

$vlan = gwmi -namespace $ns -computerName $computer -query "associators of {$connectedPort} where AssocClass=Msvm_BindsTo"
$vlanSetting = gwmi -namespace $ns -computerName $computer -query "associators of {$vlan} where AssocClass=Msvm_NetworkElementSettingData"
$vlanSetting.AccessVlan = $vlanId

For more info on how to use PS cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx

See also James O’Neil’s New and improved PowerShell Library for Hyper-V. Now with more functions and... documentation!

For all 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V PowerShell Example Scripts.zip-download

Comments (0)

Skip to main content