Automation

 View Only
Expand all | Collapse all

Collect vDS Portgroup, VMNIC and CDP information

  • 1.  Collect vDS Portgroup, VMNIC and CDP information

    Posted Apr 17, 2019 05:33 PM

    Hi,

    I found an awesome PowerCLI function that works fantastically, but I'd really like to get a slightly modified table output that included the following:

    | VMHost | PortGroup Name | VMNIC ID | VLAN No. | Switch Port ID |  Switch Port ID Connected |  Switch Name | Switch VLAN IP |

    The following article gives me almost all of the above except:

    • The vDS Portgroup Name
    • The vDS PortGroup VLAN number
    • Take into account that a VMNIC may be a member of more than 1 portgroup

    https://www.jonathanmedd.net/2013/07/obtaining-cdp-info-via-powercli.html

    I did find a different PowerCLI script that pulls the vDS portgroup VLAN, but doesn't include the configured PortGroup Name, and doesn't take into account that a VMNIC may be a member of more than one PortGroup: Cisco Discovery Protocol

    Here's my slightly modified code, but I do not know how to integrate the 3 bullet points above:

    ####################################################################################

    function Get-VMHostNetworkAdapterCDP {
    <#
    .SYNOPSIS
    Function to retrieve the Network Adapter CDP info of a vSphere host.

    .DESCRIPTION
    Function to retrieve the Network Adapter CDP info of a vSphere host.

    .PARAMETER VMHost
    A vSphere ESXi Host object

    .INPUTS
    System.Management.Automation.PSObject.

    .OUTPUTS
    System.Management.Automation.PSObject.

    .EXAMPLE
    PS> Get-VMHostNetworkAdapterCDP -VMHost ESXi01,ESXi02

    .EXAMPLE
    PS> Get-VMHost ESXi01,ESXi02 | Get-VMHostNetworkAdapterCDP
    #>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    Param
    (

    [parameter(Mandatory=$true,ValueFromPipeline=$true)]
    [ValidateNotNullOrEmpty()]
    [PSObject[]]$VMHost
    )

    begin {

    $ErrorActionPreference = 'Stop'
    Write-Debug $MyInvocation.MyCommand.Name
    $CDPObject = @()
    }

    process{

    try {
    foreach ($ESXiHost in $VMHost){

    if ($ESXiHost.GetType().Name -eq "string"){

    try {
    $ESXiHost = Get-VMHost $ESXiHost -ErrorAction Stop
    }
    catch [Exception]{
    Write-Warning "VMHost $ESXiHost does not exist"
    }
    }

    elseif ($ESXiHost -isnot [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl]){
    Write-Warning "You did not pass a string or a VMHost object"
    Return
    }

    $ConfigManagerView = Get-View $ESXiHost.ExtensionData.ConfigManager.NetworkSystem
    $PNICs = $ConfigManagerView.NetworkInfo.Pnic

    foreach ($PNIC in $PNICs){

    $PhysicalNicHintInfo = $ConfigManagerView.QueryNetworkHint($PNIC.Device)

    if ($PhysicalNicHintInfo.ConnectedSwitchPort){

    $Connected = $true
    }
    else {
    $Connected = $false
    }

    $hash = @{
    MangementAddress = $PhysicalNicHintInfo.ConnectedSwitchPort.MgmtAddr
    Switch = $PhysicalNicHintInfo.ConnectedSwitchPort.DevId
    Connected = $Connected
    PortId = $PhysicalNicHintInfo.ConnectedSwitchPort.PortId
    NIC = $PNIC.Device
    VMHost = $ESXiHost.Name
    #HardwarePlatform = $PhysicalNicHintInfo.ConnectedSwitchPort.HardwarePlatform
    #SoftwareVersion = $PhysicalNicHintInfo.ConnectedSwitchPort.SoftwareVersion
    }
    $Object = New-Object PSObject -Property $hash
    $CDPObject += $Object
    }
    }
    }
    catch [Exception] {

    throw "Unable to retrieve CDP info"
    }
    }
    end {

    Write-Output $CDPObject
    }
    }

    $MyCluster = "<Insert Clustername>"

    Get-Cluster $MyCluster| Get-VMHost | Get-VMHostNetworkAdapterCDP | Select VMHost,NIC,PortId,Connected,Switch,MangementAddress | Export-Csv .\$($MyCluster)"_CDP_Info.csv" -NoTypeInformation -UseCulture

    ##################################################################################################



  • 2.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Apr 17, 2019 06:03 PM

    I'm not sure I understand what you are trying to do here.
    A pNIC is connected to a Switch (VSS or VDS), not a portgroup.
    The only link you can establish is to list all portgroups on that switch.



  • 3.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Apr 17, 2019 11:20 PM

    A VMNIC is a label for a pNIC, right? e.g. vmnic0

    I'm looking to create a table in terms of the active and standby VMNICs/pNICs assigned to each portgroup in a vDS, and then correlate this information with the CDP info pulled from the physical switches and their ports attached to the pNICs.



  • 4.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Apr 17, 2019 11:30 PM

    E.g.

    - An ESXi host has 8 pNICs tagged vmnic0-7.

    - Each ESXi Host is connected to 2 x physical switches, 4 ports to Switch01 (odd numbered0), 4 ports to Switch-02 (even numbered)

    - Each host has a single vDS assigned with the 8 pNICs.

    - Each port group has 4 x Portgroups:

    1. Mgmt:

    Active: vmnic0, Standby: vmnic1

    2. vMotion:

    Active: vmnic1, Standby: vmnic0

    3. VM Network

    Active: vmnic2,3,4,5

    4. NFS

    Active: vmnic6, Standby: vmnic7

    - I need to display this information to the Networks team, so that they can correlate the different ESXi network traffic to their Cisco switch ports.



  • 5.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Apr 17, 2019 11:53 PM

    I'm looking to create a table as follows:

    | VMHost | PortGroup Name | VMNIC ID | VLAN No. | Switch Port ID |  Switch Port ID Connected |  Switch Name | Switch VLAN IP  |

    | ESX01    | Mgmt                     | vmnic0      | VLAN10    | Eth100/1/01      |  Connected                           | Switch01         |  192.168.10.1    |

    | ESX01    | Mgmt                     | vmnic1      | VLAN10    | Eth101/1/01      |  Connected                           | Switch02         |  192.168.11.1    |

    | ESX01    | vMotion                 | vmnic1      | VLAN20    | Eth101/1/02      |  Connected                           | Switch02         |  192.168.20.1    |

    | ESX01    | vMotion                 | vmnic0      | VLAN20    | Eth100/1/02      |  Connected                           | Switch01         |  192.168.21.1    |

    | ESX01    | VM network           | vmnic2      | VLAN30    | Eth100/1/03      |  Connected                           | Switch01         |  192.168.30.1    |

    | ESX01    | VM network           | vmnic3      | VLAN30    | Eth101/1/03      |  Connected                           | Switch02         |  192.168.31.1    |

    | ESX01    | VM network           | vmnic4      | VLAN30    | Eth100/1/04      |  Connected                           | Switch01         |  192.168.30.2    |

    | ESX01    | VM network           | vmnic5      | VLAN30    | Eth101/1/04      |  Connected                           | Switch02         |  192.168.31.2    |

    | ESX01    | NFS                       | vmnic6      | VLAN40    | Eth100/1/05      |  Connected                           | Switch01         |  192.168.40.1    |

    | ESX01    | NFS                       | vmnic7      | VLAN40    | Eth101/1/05      |  Connected                           | Switch01         |  192.168.41.1    |



  • 6.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Apr 18, 2019 01:42 PM

    Ok, you didn't mention NIC Teaming before.
    Try something like this

    Get-Cluster -PipelineVariable cluster |

    Get-VMHost -PipelineVariable esx |

    ForEach-Object -Process {

       Get-VirtualPortGroup -VMHost $esx -Standard -PipelineVariable pg |

       ForEach-Object -Process {

       @($pg.ExtensionData.Spec.Policy.NicTeaming.NicOrder.ActiveNic) +

       @($pg.ExtensionData.Spec.Policy.NicTeaming.NicOrder.StandbyNic) +

       @($pg.VirtualSwitch.ExtensionData.Spec.Policy.NicTeaming.NicOrder.ActiveNic) +

       @($pg.VirtualSwitch.ExtensionData.Spec.Policy.NicTeaming.NicOrder.StandbyNic) |

       Sort-Object -Unique |

       ForEach-Object -Process {

       $netSys.QueryNetworkHint($_) |

       ForEach-Object -Process {

       $hint = $_

       $hint.ConnectedSwitchPort |

       ForEach-Object -Process {

       New-Object PSObject -Property ([ordered]@{

       Cluster = $cluster.Name

       VMHost = $esx.Name

       Switch = $pg.VirtualSwitch.Name

       PortGroup = $pg.Name

       VLanId = $pg.VLanId

       Vmnic = $hint.Device

       IP = $_.Address

       SwitchPort = $_.PortId

       SwitchPortVLanId =  $_.VLan

       })

       }

       }

       }

       }

    }



  • 7.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Apr 18, 2019 04:07 PM

    Hi Luc,

    Is it complicated to modify the above to query an ESXi host with a vDS configured?



  • 8.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Apr 18, 2019 04:26 PM

    VDS is a completely different story.
    I'll have a look.



  • 9.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Nov 20, 2019 12:41 PM

    LucD,

    When attempting to run this as a script it has an error on the line:

    $netSys.QueryNetworkHint ($_)  |

    stating it cannot call a method on a null-valued expression. I don't see where the $netSys variable is defined prior to this line may be the issue.



  • 10.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Nov 20, 2019 12:56 PM

    There is a line missing, this should work

    Get-Cluster -PipelineVariable cluster |

    Get-VMHost -PipelineVariable esx |

    ForEach-Object -Process {

        $netSys = Get-View -Id $esx.ExtensionData.ConfigManager.NetworkSystem

        Get-VirtualPortGroup -VMHost $esx -Standard -PipelineVariable pg |

        ForEach-Object -Process {

            @($pg.ExtensionData.Spec.Policy.NicTeaming.NicOrder.ActiveNic) +

            @($pg.ExtensionData.Spec.Policy.NicTeaming.NicOrder.StandbyNic) +

            @($pg.VirtualSwitch.ExtensionData.Spec.Policy.NicTeaming.NicOrder.ActiveNic) +

            @($pg.VirtualSwitch.ExtensionData.Spec.Policy.NicTeaming.NicOrder.StandbyNic) |

            Sort-Object -Unique |

            ForEach-Object -Process {

                $netSys.QueryNetworkHint($_) |

                ForEach-Object -Process {

                    $hint = $_

                    $hint.ConnectedSwitchPort |

                    ForEach-Object -Process {

                        New-Object PSObject -Property ([ordered]@{

                                Cluster          = $cluster.Name

                                VMHost           = $esx.Name

                                Switch           = $pg.VirtualSwitch.Name

                                PortGroup        = $pg.Name

                                VLanId           = $pg.VLanId

                                Vmnic            = $hint.Device

                                IP               = $_.Address

                                SwitchPort       = $_.PortId

                                SwitchPortVLanId = $_.VLan

                            })

                    }

                }

            }

        }

    }



  • 11.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 21, 2021 08:26 AM

     ,

    Is it possible to add an export to CSV.

     

    I tried and am going from error to error.



  • 12.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 21, 2021 09:13 AM

    You can 'pipe' everything to an Export-Csv after the last closing curly brace.

    What errors are you getting?



  • 13.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 21, 2021 10:46 AM

    I tried to do the += with table and collector as a collection found from another script.

    Will try a straight pipe out to csv.



  • 14.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 21, 2021 11:00 PM

    A straight pipe worked, thank you.

     

    You mentioned that a vDS is different. Is there a vDS version of the script?

    I tried to remove the -standard from the Get-VirtualPortGroup but it doesn't look like it did anything

     

    *Edit* did try to replace it with Get-VDPortgroup, but that did not work.



  • 15.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 22, 2021 07:06 AM

    Like I stated earlier in this thread, a VDS uses a different logic, which requires a different script.



  • 16.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 22, 2021 12:00 PM

    No chance you have one up your sleeve?

     

    If not, thats ok.



  • 17.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 22, 2021 01:02 PM

    No, I didn't, but I got intrigued 
    Just came up with this quick-and-dirty snippet.
    Give it a try

     

    Get-Cluster -PipelineVariable cluster |
        Get-VMHost -PipelineVariable esx |
        ForEach-Object -Process {
            $netSys = Get-View -Id $esx.ExtensionData.ConfigManager.NetworkSystem
            Get-VDSwitch -VMHost $esx -PipelineVariable vdsw |
                ForEach-Object -Process {
                    $obj = [ordered]@{
                        Cluster          = $cluster.Name
                        VMHost           = $esx.Name
                        Switch           = $vdsw.Name
                        Portgroup        = ''
                        Uplink           = ''
                        pNIC             = ''
                        TeamType         = ''
                        Device           = ''
                        IP               = ''
                        DevId            = ''
                        SwitchPort       = ''
                        SwitchPortVLanId = ''
                    }
                    $uplinkTab = @{}
                    Get-VDPort -VDSwitch $vdsw -Uplink |
                        where { $_.ExtensionData.Connectee.ConnectedEntity -eq $esx.ExtensionData.MoRef } |
                        ForEach-Object -Process {
                            $uplinkTab.Add($_.ExtensionData.Config.Name, $_.ExtensionData.Connectee.NicKey)
                        }
                        Get-VDPortgroup -VDSwitch $vdsw -PipelineVariable vdpg | where { -not $_.IsUplink } |
                            ForEach-Object -Process {
                                $obj['Portgroup'] = $vdpg.Name
                                if ($vdpg.ExtensionData.Config.DefaultPortConfig.UplinkTeamingPolicy.UplinkPortOrder.ActiveUplinkPort) {
                                    $vdpg.ExtensionData.Config.DefaultPortConfig.UplinkTeamingPolicy.UplinkPortOrder.ActiveUplinkPort |
                                        ForEach-Object -Process {
                                            $hint = $netSys.QueryNetworkHint($uplinkTab[$_])
                                            $obj['Uplink'] = $_
                                            $obj['pNIC'] = $uplinkTab[$_]
                                            $obj['TeamType'] = 'Active'
                                            $obj['Device'] = $hint.Device
                                            $hint.ConnectedSwitchPort | ForEach-Object -Process {
                                                $obj['DevId'] = $_.DevId
                                                $obj['IP'] = $_.Address
                                                $obj['SwitchPort'] = $_.PortId
                                                $obj['SwitchPortVLanId'] = $_.VLan
                                                New-Object -TypeName PSObject -Property $obj
                                            }
                                        }
                                    }
                                    if ($vdpg.ExtensionData.Config.DefaultPortConfig.UplinkTeamingPolicy.UplinkPortOrder.StandbyUplinkPort) {
                                        $vdpg.ExtensionData.Config.DefaultPortConfig.UplinkTeamingPolicy.UplinkPortOrder.StandbyUplinkPort |
                                            ForEach-Object -Process {
                                                $hint = $netSys.QueryNetworkHint($uplinkTab[$_])
                                                $obj['Uplink'] = $_
                                                $obj['pNIC'] = $uplinkTab[$_]
                                                $obj['TeamType'] = 'Standby'
                                                $obj['Device'] = $hint.Device
                                                $hint.ConnectedSwitchPort | ForEach-Object -Process {
                                                    $obj['DevId'] = $_.DevId
                                                    $obj['IP'] = $_.Address
                                                    $obj['SwitchPort'] = $_.PortId
                                                    $obj['SwitchPortVLanId'] = $_.VLan
                                                    New-Object -TypeName PSObject -Property $obj
                                                }
                                            }
                                        }
                                    } 
                                }
                            }

     

     



  • 18.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 23, 2021 12:08 AM

    Looks awesome,

    $hint.Device

     Seems to reference the vNic uplink, not the actual physical Switch.

     

    I did try below, but i came up blank.

    $hint.ConnectedSwitchPort | ForEach-Object -Process {
    $obj['Device'] = $_.Device
    and
    $obj['Device'] =  $hint.ConnectedSwitchPort.Device


  • 19.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 23, 2021 09:35 AM

    Not sure what the issue is.
    The teaming (active and standby) on VDS is expressed with the Uplinks.
    I use a table to link the Uplinks to the pNICs on each ESXi node.
    This seems to work for me



  • 20.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 24, 2021 07:31 AM

    oh the teaming bit is fine.

    I thought the idea was to get the full cdp info from each vnic. It only gets the physical connected switch IP, but not the name of the switch. Having both the IP and names makes it allow easier to sort.



  • 21.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Feb 24, 2021 08:43 AM

    No, this snippet is only for all pNICs connected to VDS.
    A full script, that handles all pNICs, unused/VSS/VDS, would require combining the 2 snippets in this thread together with some code to handle the unused pNICs.

    If you mean the CDP DevId value, I added that in the code above.
    In fact, you can add all CDP info in the report.



  • 22.  RE: Collect vDS Portgroup, VMNIC and CDP information

    Posted Jul 14, 2023 04:11 PM

    What IDE do you use?