Steve Borba

My notes, I hope they help you, feel free to comment/add to them

ESXi Export LLDP/CDP

I combined a few scripts and tried to speed them up, originally it took 30-40 minutes, but I got it down to 3-5.
The majority of the script came from here. I also took some from Jason for the progress bars, but added the ETA seconds.

 #Prompt User for VC addresses, if more than one, ask for credentials to store/use - instead of having vmware prompt multiple times
$VCs = (Read-Host -Prompt 'Input VC addresses separated by commas').Split(",")
if ($VCs.count -gt 1) {
  $Creds = Get-Credential
}
if ($Creds) {
  $VIConns = Connect-VIServer -AllLinked $VCs -Credential $Creds
} else {
  $VIConns = Connect-VIServer -AllLinked $VCs
}

#Get list of all hosts
$Esxihosts = Get-VMHost | Where-Object {$_.ConnectionState -eq "Connected"}

#Initialize variables
$Collection = @()
$LoopAverage = 0
$Max = $Esxihosts.count
$Speed = 50
$Delta = 0
$i=0
foreach ($Esxihost in $Esxihosts) {
   $StartLoopTime = Get-Date
   $i++
  if ( -not (($i -gt 6) -or ($i -gt ($Max * 0.1)))) {
    #for the first 6 loops (or 10%, whichever comes first), don't give ETA and say we are determining the average
    Write-Progress -id 1 -Activity "Extracting Port Information" -Status ("Working on "+$ESXihost.Name.Split(".")[0]) -PercentComplete (($i/$Max)*100)
    Write-Progress -ParentId 1 -id 2 -Activity "Determining Average"
  } else {
    #We now have an average duration of the loop, provide ETA based on the number of loops remaining
    Write-Progress -id 1 -Activity "Extracting Port Information" -Status ("Working on "+$ESXihost.Name.Split(".")[0]) -PercentComplete (($i/$Max)*100) -SecondsRemaining ($LoopAverage*($Max - $i)/1000)
    #give feedback to show if the average is increasing or decreasing, 33% change is the max displayed, but average out the display to keep the bar from full flapping back and forth
    if ( [Math]::Abs($Delta) -lt ($LoopAverage/3) ) { $Speed = (((50 - ($Delta/$LoopAverage)*150)+$Speed*3)/4) } else { if ( $Delta -lt 0 ) { $Speed = ($Speed + 99)/2 } else { $Speed = $Speed/2 } }
    if ( $Speed -gt 60 ) { $Text = "Speeding up" } Else { if ( $Speed -lt 40 ) { $Text = "Slowing down" } Else { $Text = "Maintaining Speed"}}
    Write-Progress -ParentId 1 -id 2 -Activity ("Average Loop Time: "+[Math]::round($LoopAverage / 100)/10 +" Seconds") -PercentComplete $Speed -CurrentOperation ($Text)
  }
  Write-Progress -id 3 -ParentId 2 -Activity "Pulling data" -Status ("getting esxcli data") -PercentComplete (5)
   $Esxcli = Get-EsxCli -VMHost $Esxihost
   $Esxcli_niclist =  $esxcli.network.nic.list()
  Write-Progress -id 3 -ParentId 2 -Activity "Pulling data" -Status ("Grabbing View data") -PercentComplete (50)
   $Esxihostview = $EsxiHost | Get-View
   $Networkview = $Esxihostview.Configmanager.Networksystem | Get-View
  Write-Progress -id 3 -ParentId 2 -Activity "Pulling data" -Status ("getting pnic data") -PercentComplete (75)
   $VMnics = $Esxihost | get-vmhostnetworkadapter -Physical
   $j=0
   Foreach ($VMnic in $VMnics){
    Write-Progress -id 3 -ParentId 2 -Activity "Pulling data" -Status ("Putting data together for "+$VMnic.Name) -PercentComplete (80+($j++/$VMnics.count*20))
     $realInfo = $Networkview.QueryNetworkHint($VMnic)
     $pNic = $Esxcli_niclist | where-object {$vmnic.name -eq $_.name} | Select-Object Description, Link       
     if ($realInfo.lldpinfo -ne $null) {
       #LLDP is available, built an object based on it and add to collection
       $LLDPinfo = $realInfo.lldpinfo
       $SwitchName = $realInfo.lldpinfo.Parameter | Where-Object {$_.Key -eq "System Name"} | Select-Object -ExpandProperty Value
       $SwitchIP = $realInfo.lldpinfo.Parameter | Where-Object {$_.Key -eq "Management Address"} | Select-Object -ExpandProperty Value
       $SwitchPortVlanID = $realInfo.lldpinfo.Parameter | Where-Object {$_.Key -eq "Vlan ID"} | Select-Object -ExpandProperty Value
       $SwitchPortMTU = $realInfo.lldpinfo.Parameter | Where-Object {$_.Key -eq "MTU"} | Select-Object -ExpandProperty Value
       $Table = New-Object PSObject
       $Table | Add-Member -Name EsxName -Value $esxihost.Name -MemberType NoteProperty
       $Table | Add-Member -Name VMNic -Value $VMnic -MemberType NoteProperty
       $Table | Add-Member -Name vSwitch -Value $vSwitch -MemberType NoteProperty
       $Table | Add-Member -Name Link -Value $pNic.Link -MemberType NoteProperty
       $Table | Add-Member -Name PortNo -Value $LLDPinfo.PortId -MemberType NoteProperty
       $Table | Add-Member -Name SwitchName -Value $SwitchName -MemberType NoteProperty
       $Table | Add-Member -Name SwitchIP -Value $SwitchIP -MemberType NoteProperty
       $Table | Add-Member -Name MacAddress -Value $vmnic.Mac -MemberType NoteProperty
       $Table | Add-Member -Name SpeedMB -Value $vmnic.ExtensionData.LinkSpeed.SpeedMB -MemberType NoteProperty
       $Table | Add-Member -Name Duplex -Value $vmnic.ExtensionData.LinkSpeed.Duplex -MemberType NoteProperty
       $Table | Add-Member -Name Pnic-Vendor -Value $pNic.Description -MemberType NoteProperty
       $Table | Add-Member -Name Pnic-drivers -Value $vmnic.ExtensionData.Driver -MemberType NoteProperty
       $Table | Add-Member -Name PCI-Slot -Value $vmnic.ExtensionData.Pci -MemberType NoteProperty
       $collection += $Table
     } else {
       #LLDP is not available, built an object based on CDP and add to collection
       $CDPextended = $realInfo.connectedswitchport
       $Table = New-Object PSObject
       $Table | Add-Member -Name EsxName -Value $esxihost.Name -MemberType NoteProperty
       $Table | Add-Member -Name VMNic -Value $VMnic -MemberType NoteProperty
       $Table | Add-Member -Name vSwitch -Value $vSwitch -MemberType NoteProperty
       $Table | Add-Member -Name Link -Value $pNic.Link -MemberType NoteProperty
       $Table | Add-Member -Name PortNo -Value $CDPextended.PortId -MemberType NoteProperty
       $Table | Add-Member -Name SwitchName -Value $CDPextended.devID -MemberType NoteProperty
       $Table | Add-Member -Name SwitchIP -Value $CDPextended.Address -MemberType NoteProperty
       $Table | Add-Member -Name MacAddress -Value $vmnic.Mac -MemberType NoteProperty
       $Table | Add-Member -Name SpeedMB -Value $vmnic.ExtensionData.LinkSpeed.SpeedMB -MemberType NoteProperty
       $Table | Add-Member -Name Duplex -Value $vmnic.ExtensionData.LinkSpeed.Duplex -MemberType NoteProperty
       $Table | Add-Member -Name Pnic-Vendor -Value $pNic.Description -MemberType NoteProperty
       $Table | Add-Member -Name Pnic-drivers -Value $vmnic.ExtensionData.Driver -MemberType NoteProperty
       $Table | Add-Member -Name PCI-Slot -Value $vmnic.ExtensionData.Pci -MemberType NoteProperty
       $collection += $Table
     }
   }
  
  #update loop time and loop average by using a 10% weight (creates an average based on the last 10% of loops performed)
  $Delta = (New-TimeSpan -Start $StartLoopTime -End (Get-Date)).TotalMilliseconds - $LoopAverage
  if ( (100*($i/$Max)) -lt 10) { $LoopAverage = $LoopAverage + $Delta/$i } Else {
                                 $LoopAverage = $LoopAverage + $Delta/($Max*.1)
     }
}
Write-Progress -id 1 -PercentComplete 100 -Activity "Done"

#Prompt user for filename to export, but allow default to desktop called output.csv
$ExportFile = ""
$DefaultExportFile = ${env:userprofile}+"\Desktop\output.csv"
$ExportFile = Read-Host -Prompt "Enter File Path (Default: $DefaultExportFile) [Enter to Accept]"
If ($ExportFile.Length -eq 0) {$ExportFile = $DefaultExportFile}
$collection | Export-Csv $ExportFile 

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>