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 param( $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'" return } # 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" return } # 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" return } # 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 break } } } 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 $vlanSetting.Put()
# Modify VLAN setting for VM
param( $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'" return }
# 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" return }
# 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" return }
# 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 break } } }
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 $vlanSetting.Put()
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