Things I Keep Forgetting¶
- Last Updated: June, 2025
VMware portgroup security settings¶
You may have come across these VMware vswitch portgroup security settings but never known what they do. I've had to use them with network simulation software like Cisco Modeling Labs and also when running virtual firewalls such as the vFTD.
Promiscuous Mode
:- When enabled, a virtual network adapter can observe all traffic on the virtual switch, regardless of the destination MAC address.
- The vFTD won't see any traffic if this is not enabled.
MAC Address Changes
:- This controls whether the virtual switch accepts requests to change the effective MAC address used by the VM's operating system.
Forged Transmits
:- Determines whether the hypervisor allows a virtual machine to send network traffic with a MAC address different from the one assigned to its virtual network adapter by the hypervisor.
- In my use case the vFTD was in transparent mode ("bump in the wire") and therefore acts as a Layer 2 bridge between segments which means it does not modify the MAC address of the passing traffic. It receives a frame from
192.168.10.1
and sends it to192.168.10.2
but keeps the original MAC address (endpoint 1) as the source. Since it will be forwarding frames with a source MAC address (endpoint 1) that does not match its own vNIC's MAC address without this configured asAccept
the traffic would be dropped.
Checking host connectivity¶
Here's a sample script I use to test connectivity of ESXi hosts. It outputs a table shown in the screenshot below.
check-host-connectivity.py
from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim
import ssl
from prettytable import PrettyTable
import os
# These links seem to have some details on the Managed Object Types found below (e.g. ViewManager or distributedVirtualSwitch)
# https://vdc-download.vmware.com/vmwb-repository/dcr-public/dce91b06-cc93-42d6-b277-78fb13a16d6e/7d3494a5-bca7-400f-a18f-f539787ec798/left-pane.html
# https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere-sdks-tools/8-0/web-services-sdk-programming-guide.html
def get_vcenter_connection(vcenter_host, username, password):
try:
context = ssl._create_unverified_context()
vcenter_connection = SmartConnect(
host=vcenter_host,
user=username,
pwd=password,
sslContext=context
)
return vcenter_connection
except Exception as e:
print(f"Failed to connect to vCenter: {e}")
return None
def get_distributed_portgroup_map(content):
portgroup_map = {}
try:
portgroups = content.viewManager.CreateContainerView(
content.rootFolder, [vim.DistributedVirtualPortgroup], True
)
for portgroup in portgroups.view:
dvs_name = portgroup.config.distributedVirtualSwitch.name
portgroup_map[portgroup.key] = dvs_name
except Exception as e:
print(f"Error retrieving DVS Portgroups: {e}")
return portgroup_map
def determine_connectivity_status(active_uplinks, standby_uplinks):
# This determine the connectivity status based on uplink counts.
if len(active_uplinks) >= 2:
return "Dual Connected (Active)"
elif len(active_uplinks) == 1 and standby_uplinks:
return "Single Connected (Active/Standby)"
elif len(active_uplinks) == 1:
return "Single Connected (Active)"
else:
return "No Active Uplinks"
def get_vswitch_uplink_status(network_system):
vswitch_data = []
# Iterate through standard vSwitches
for vswitch in network_system.networkInfo.vswitch:
uplinks = []
standby_uplinks = []
try:
teaming_policy = vswitch.spec.policy.nicTeaming
if teaming_policy is not None:
uplinks = teaming_policy.nicOrder.activeNic or []
standby_uplinks = teaming_policy.nicOrder.standbyNic or []
except AttributeError:
# Handle cases where nicTeaming is not configured
pass
vswitch_data.append({
"switch_name": vswitch.name,
"active_uplinks": uplinks,
"standby_uplinks": standby_uplinks,
"status": determine_connectivity_status(uplinks, standby_uplinks)
})
return vswitch_data
def get_dvs_uplink_status(host, portgroup_map):
dvs_data = []
try:
for proxy_switch in host.configManager.networkSystem.networkInfo.proxySwitch:
uplinks = []
standby_uplinks = []
dvs_name = "Unknown DVS"
# Use uplinkPortgroupKey to determine the DVS name
if hasattr(proxy_switch.spec.backing, 'pnicSpec'):
for pnic_spec in proxy_switch.spec.backing.pnicSpec:
if hasattr(pnic_spec, 'uplinkPortgroupKey') and pnic_spec.uplinkPortgroupKey:
uplinks.append(pnic_spec.pnicDevice)
dvs_name = portgroup_map.get(pnic_spec.uplinkPortgroupKey, "Unknown DVS")
dvs_data.append({
"switch_name": dvs_name,
"active_uplinks": uplinks,
"standby_uplinks": standby_uplinks,
"status": determine_connectivity_status(uplinks, standby_uplinks)
})
except Exception as e:
print(f"Error retrieving DVS information for host {host.name}: {e}")
return dvs_data
def main():
vcenter_host = os.getenv("VCENTER_HOST") # Replace with your vCenter host environment variable name
username = os.getenv("VCENTER_USERNAME") # Replace with your username environment variable name
password = os.getenv("VCENTER_PASSWORD") # Replace with your password environment variable name
if not all([vcenter_host, username, password]):
raise ValueError("Missing required environment variables: VCENTER_HOST, VCENTER_USERNAME, or VCENTER_PASSWORD")
vcenter_connection = get_vcenter_connection(vcenter_host, username, password)
if not vcenter_connection:
print("Failed to connect to vcentre")
return
try:
content = vcenter_connection.RetrieveContent()
portgroup_map = get_distributed_portgroup_map(content)
# Retrieve all hosts
container = content.viewManager.CreateContainerView(
content.rootFolder, [vim.HostSystem], True
)
hosts = container.view
# This table is used for the output
table = PrettyTable()
table.field_names = ["Host", "Switch Name", "Active Uplinks", "Standby Uplinks", "Status"]
# Traverse each host and find vSwitch/DVS uplinks
for host in hosts:
network_system = host.configManager.networkSystem
# Get standard vSwitch uplink status
vswitch_data = get_vswitch_uplink_status(network_system)
for vswitch in vswitch_data:
table.add_row([
host.name,
vswitch["switch_name"],
", ".join(vswitch["active_uplinks"]),
", ".join(vswitch["standby_uplinks"]),
vswitch["status"]
])
# Get DVS uplink status
dvs_data = get_dvs_uplink_status(host, portgroup_map)
for dvs in dvs_data:
table.add_row([
host.name,
dvs["switch_name"],
", ".join(dvs["active_uplinks"]),
", ".join(dvs["standby_uplinks"]),
dvs["status"]
])
print(table)
except Exception as e:
print(f"Error gathering data: {e}")
finally:
Disconnect(vcenter_connection)
if __name__ == "__main__":
main()