Public/Test-AnyStackNetworkConfiguration.ps1
|
function Test-AnyStackNetworkConfiguration { <# .SYNOPSIS Audits virtual switch configurations across ESXi hosts in a cluster for VCF standards. .DESCRIPTION This function performs a deep-dive audit of Standard vSwitches (VSS) and Distributed vSwitches (VDS). It evaluates security policies, MTU consistency, uplink redundancy, and discovery protocol (CDP/LLDP) status. Optimized for large-scale environments using Get-View. .PARAMETER Server VIServer connection object. .PARAMETER ClusterName Name of the cluster to audit. .EXAMPLE Test-AnyStackNetworkConfiguration -Server $vc -ClusterName "Cl01-Prod" #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] $Server, [Parameter(Mandatory=$true)] [string]$ClusterName ) process { $ErrorActionPreference = 'Stop' try { # 1. Fetch Cluster & Hosts Write-Verbose "Fetching cluster: $ClusterName" $clusterView = Get-View -Server $Server -ViewType ClusterComputeResource -Filter @{"Name"="^$ClusterName$"} -Property Name,Host -ErrorAction Stop if (-not $clusterView) { throw "Cluster '$ClusterName' not found." } # 2. Fetch Host Network Configs (VSS & VDS details) # Fetching: vSwitch config, PortGroups, ProxySwitch (VDS on host), Discovery Protocol $hostProps = @( "Name", "Config.Network.Vswitch", "Config.Network.Portgroup", "Config.Network.ProxySwitch", "Config.Network.DnsConfig", "Config.Network.Vnic", "Config.Network.Pnic" ) $hosts = Get-View -Server $Server -Id $clusterView.Host -Property $hostProps $auditResults = foreach ($h in $hosts) { Write-Verbose "Auditing Host: $($h.Name)" # --- Audit Standard vSwitches (VSS) --- if ($h.Config.Network.Vswitch) { foreach ($vss in $h.Config.Network.Vswitch) { $uplinkCount = 0 if ($vss.Pnic) { $uplinkCount = $vss.Pnic.Count } # Security Policy Audit $secPolicy = $vss.Spec.Policy.Security $isPromiscuous = $secPolicy.AllowPromiscuous -eq $true $isMacChanges = $secPolicy.MacChanges -eq $true $isForgedTransmits = $secPolicy.ForgedTransmits -eq $true [PSCustomObject]@{ Host = $h.Name SwitchType = "VSS" SwitchName = $vss.Name MTU = $vss.Spec.Mtu UplinkCount = $uplinkCount UplinkRedundancy = ($uplinkCount -ge 2) PromiscuousMode = $isPromiscuous MacChanges = $isMacChanges ForgedTransmits = $isForgedTransmits DiscoveryProto = $null # VSS discovery is handled at the spec level or switch level Alert = if ($uplinkCount -lt 2) { "Low Uplink Redundancy" } elseif ($isPromiscuous) { "Security: Promiscuous Mode Active" } else { "None" } } } } # --- Audit Distributed vSwitches (VDS) on the Host --- if ($h.Config.Network.ProxySwitch) { foreach ($proxy in $h.Config.Network.ProxySwitch) { $uplinkCount = 0 if ($proxy.Uplink) { $uplinkCount = $proxy.Uplink.Count } # Note: Deep security policies for VDS are usually at the DVPortgroup level # but we can check MTU and basic proxy info here. [PSCustomObject]@{ Host = $h.Name SwitchType = "VDS (Proxy)" SwitchName = $proxy.DvsName MTU = $proxy.Mtu UplinkCount = $uplinkCount UplinkRedundancy = ($uplinkCount -ge 2) PromiscuousMode = $null # Checked at DVPortgroup level MacChanges = $null ForgedTransmits = $null DiscoveryProto = if ($null -ne $proxy.Config.DiscoveryProtocol -and $null -ne $proxy.Config.DiscoveryProtocol.Type) { $proxy.Config.DiscoveryProtocol.Type } else { "Unknown" } Alert = if ($uplinkCount -lt 2) { "Low Uplink Redundancy" } else { "None" } } } } } # 3. Global VDS Portgroup Security Audit (Cross-cluster) # This identifies configuration drift in Portgroups Write-Verbose "Performing Global VDS Portgroup Audit..." $dvpgViews = Get-View -Server $Server -ViewType DistributedVirtualPortgroup -Property Name,Config $pgAudit = foreach ($pg in $dvpgViews) { # Only check if it looks like it belongs to our clusters (or just check all active) # Filtering logic: Usually VDS portgroups aren't scoped by cluster MoRef as easily as VSS, # but we'll flag any that violate security standards. $sec = $pg.Config.DefaultPortConfig.SecurityPolicy if ($sec.AllowPromiscuous.Inherited -eq $false -and $sec.AllowPromiscuous.Value -eq $true) { [PSCustomObject]@{ Host = "VDS-Global" SwitchType = "DVPortgroup" SwitchName = $pg.Name MTU = $null UplinkCount = $null UplinkRedundancy = $null PromiscuousMode = $true MacChanges = $sec.MacChanges.Value ForgedTransmits = $sec.ForgedTransmits.Value DiscoveryProto = $null Alert = "Security: Promiscuous Mode enabled on DVPortgroup" } } } Write-Output ($auditResults + $pgAudit) } catch { Write-Error "Failed to audit network configuration: $($_.Exception.Message)" } } } |