Script – ESXi vmnic Uplink Details

Um in meinen VMware vSphere Clustern zu überprüfen, ob für alle Distributed Virtual Switches (DVS) die optimale Redundanz über alle Komponenten hinweg gegeben ist habe ich mir ein PowerCLI Skript geschrieben, welches die ESXi vmnic Uplink Details reportet.

Was soll der Report beinhalten:

  • vSphere Cluster
  • ESXi Host Name
  • vmnic Name
  • MAC Adresse
  • PCI Adresse
  • DVS oder vSwitch2828
  • Verbundener physikalischer Switch Port
  • Verbundener physikalischer Switch
  • IP des verbundenen physikalischer Switch

Mit diesen Informationen lässt sich dann bis zum ersten physikalischen Switch (meist Leaf Switch  – Mehr Details im VMware Validated Design 4.0 Documentation Center) sauber überprüfen ob die optimale Redundanz über alle Komponenten hinweg gegeben ist ist.

ESXi vmnic Uplink Details - PS Result

ESXi vmnic Uplink Details – PS Result

Was ist die Optimale Redundanz

Für mich ist die optimale Redundanz wenn ein DVS, mindestens zwei vmnic`s hat und diese auf unterschiedlichen PCI Karten des Hosts sind. Die dazugehörigen Uplinks der Netzwerkkarten sollten dann wiederum an zwei unterschiedlichen physikalisches Switches angebunden sein. Somit haben wir keinen Single Point of Failure.

ESXi vmnic Uplink Details - Diagram

ESXi vmnic Uplink Details – Diagram

Natürlich ist damit das Thema Netzwerkredundanz noch lange nicht abgeschlossen, aber mehr können wir von Host-Seite leider nicht überprüfen.

Weiterführend kann ich nur erneut die VMware Validated Design 4.0 Dokumente empfehlen und hierzu speziell den Abschnitt Physical Network Architecture.

Report der ESXi vmnic Uplink Details

Um alle relevanten Informationen zu sammeln ist es notwendig zusätzlich zu den ESXi Konfigurationsparameter auch auf die CDP Daten zurückzugreifen (auch LLDP Daten wäre mit einem DVS denkbar). Für die Aufbereitung der CDP Daten des ESXi Hosts habe ich mich wieder mal an einer Funktion von Luc Dekens aus der PowerCLI Community bedient (VMware PowerCLI Community – Cisco Discovery Protocol) und etwas erweitert in meine eigene PowerCLI Funktion integriert.

Simpler Aufruf des Moduls:

Get-UplinkDetails -Clustername MyClluste01 | ft -AutoSize

Aufruf mir angepasster Sortierung:

Get-UplinkDetails -Clustername MyCluster* | Sort Clustername, Hostname, DVS | ft -AutoSize

Export des Reports:

Get-UplinkDetails -Clustername * | Export-Csv C:\export.csv

Sind für einen Port keine CDP Informationen vorhanden, wird dies von dem Script abgefangen:

ESXi vmnic Uplink Details - PS Result and Command

ESXi vmnic Uplink Details – PS Result and Command

 

function Get-UplinkDetails {
<#	
    .NOTES
    ===========================================================================
    Created by: Markus Kraus
    Twitter: @VMarkus_K
    Private Blog: mycloudrevolution.com
    ===========================================================================
    Changelog:  
    2017.03 ver 1.0 Base Release  
    ===========================================================================
    External Code Sources: 
    Get-CDP Version from @LucD22
    https://communities.vmware.com/thread/319553
    ===========================================================================
    Tested Against Environment:
    vSphere Version: vSphere 6.0 U2
    PowerCLI Version: PowerCLI 6.3 R1
    PowerShell Version: 4.0
    OS Version: Server 2012 R2
    Keyword: ESXi, Network, CDP, DVS, vSwitch, VMNIC 
    ===========================================================================

    .DESCRIPTION
    This cmdlet collects detailed informations about your ESXi Host connections to pSwitch and DVS / vSwitch

    .Example
    Get-UplinkDetails -Clustername * | ft -AutoSize

    .Example
    Get-UplinkDetails -Clustername MyCluster001 | ft -AutoSize

    .Example
    Get-UplinkDetails -Clustername MyCluster* | Sort Clustername, Hostname, DVS | ft -AutoSize

    .PARAMETER Clustername
    Your vSphere Cluster Name or Wildcard


#Requires PS -Version 4.0
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
#>

[CmdletBinding()]
param( 
    [Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)]
        [String] $Clustername
        
)

Begin {
    $Validate = $True

    if (($myCluster = Get-Cluster -Name $Clustername).count -lt 1) {
       $Validate = $False
       throw "No Cluster '$myCluster' found"
    }
    if (($myHosts = $myCluster | Get-VMHost).count -lt 1) {
       $Validate = $False
       throw "No Hosts in Cluster '$myCluster' found"
    }

    function Get-CDP ($VMhost){
        $VMhostProxySwitch = $VMhost.NetworkInfo.ExtensionData.ProxySwitch 
        $VMhostSwitch = $VMhost.NetworkInfo.VirtualSwitch

        $objReport = @()
        $VMhost| %{Get-View $_.ID} | 
        %{ Get-View $_.ConfigManager.NetworkSystem} | 
        %{ foreach($physnic in $_.NetworkInfo.Pnic){ 
     
            $obj = "" | Select-Object Clustername,Hostname,VMNIC,PCI,MAC,DVS,vSwitch,CDP_Port,CDP_Device,CDP_Address   
     
            $pnicInfo = $_.QueryNetworkHint($physnic.Device) 
            foreach($hint in $pnicInfo){ 
                $obj.Clustername = $VMhost.parent.name
                $obj.Hostname = $VMhost.name 
                $obj.VMNIC = $physnic.Device
                $obj.PCI = $physnic.PCI
                $obj.MAC = $physnic.Mac
                if ($backing = ($VMhostProxySwitch | where {$_.Spec.Backing.PnicSpec.PnicDevice -eq $physnic.Device}).DvsName) {
                    $obj.DVS = $backing
                    } else {
                        $obj.DVS = "-No Backing-"
                        }
                if ($backing = ($VMhostSwitch | where {$_.Nic -eq $physnic.Device}).Name) {
                    $obj.vSwitch = $backing
                    } else {
                        $obj.vSwitch = "-No Backing-"
                        }
                if( $hint.ConnectedSwitchPort ) { 
                    $obj.CDP_Port = $hint.ConnectedSwitchPort.PortId
                    $obj.CDP_Device = $hint.ConnectedSwitchPort.DevId
                    $obj.CDP_Address = $hint.ConnectedSwitchPort.Address  
                    } else { 
                        $obj.CDP_Port = "-No Info-" 
                        $obj.CDP_Device = "-No Info-" 
                        $obj.CDP_Address = "-No Info-" 
                        } 
                

            } 
            $objReport += $obj 
            } 
        } 
        $objReport 
    } 
  
}

Process {

    $MyView = @()

    if ($Validate -eq $True) {
  
        foreach ($myHost in $myHosts) {

        $CDP = Get-CDP $myHost
        $MyView += $CDP        

		}
           
       $MyView | Sort Clustername, Hostname, VMNIC

    }
    }
}

Zeile 63-107: Von mir erweiterte Funktion von Luc Dekens aus der PowerCLI Community (VMware PowerCLI Community – Cisco Discovery Protocol)

2 Comments

  1. maxr91 21. März 2022
    • Markus Kraus 21. März 2022

Leave a Reply