Skip to content

Instantly share code, notes, and snippets.

@changbowen
Last active March 13, 2020 09:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save changbowen/2eb8db8b212719e5e53a796152350a29 to your computer and use it in GitHub Desktop.
Save changbowen/2eb8db8b212719e5e53a796152350a29 to your computer and use it in GitHub Desktop.
Getting CDP (Cisco Discovery Protocol) information via PowerShell on specified list of ESXi hosts
<#param([string]$VMhost, [string]$Cluster, [string]$VCServer)
If ($VMhost) {$vmh = Get-VMHost -Name $VMhost}
If ($Cluster) {$vmh = Get-Cluster $Cluster | Get-VMHost}
If ($VCServer) {$vmh = Get-VMhost -Server $VCServer}
#>
param(
[Parameter(ValueFromPipeline)]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMHost = $(Get-VMHost)
)
function collectProperties {
param (
[VMware.Vim.ServiceInstance]$content,
[VMware.Vim.View]$view_ref,
[VMware.Vim]$obj_type,
[array]$path_set,
[bool]$incl_ref,
[string]$key)
if (!$path_set.Contains($key)) { throw "Key is not one of the paths in path_set." }
$collector = $content
}
if ($input.Length -eq 0) {$input = $VMHost}
$input | % {
$vmhostview = VMware.VimAutomation.Core\Get-View $_.ID
$esxname = $vmhostview.Name
$nsview = VMware.VimAutomation.Core\Get-View $vmhostview.ConfigManager.NetworkSystem
foreach ($physnic in $nsview.NetworkInfo.Pnic) {
$DevId = $null
$Address = $null
$PortId = $null
$vLan = $null
$LinkSpeed_Mb = $physnic.LinkSpeed.SpeedMb
$pnicInfo = $nsview.QueryNetworkHint($physnic.Device)
foreach ( $hint in $pnicInfo ) {
$csp = $hint.ConnectedSwitchPort
if ($csp) {
$DevId = $csp.DevId
$Address = $csp.Address
$PortId = $csp.PortId
$vLan = $csp.vLan
}
$csp = $null
}
[PSCustomObject]@{
VMHost = $esxname;
VMNic = $physnic.Device;
LinkSpeed_Mb = $LinkSpeed_Mb;
DevId = $DevId;
Address = $Address;
PortId = $PortId;
vLan = $vLan
}
}
} | sort -Property VMHost,VMNic | ft -a
<#
.SYNOPSIS
Get CDP information from one or more ESX hosts.
.PARAMETER VMHost
VMHost can be a list of the below entries:
- FQDN name of the host
- VMware.Vim.HostSystem (return type of 'Get-View -ViewType HostSystem')
- VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl (return type of 'Get-VMHost')
.INPUTS
One or more VMHost object can be piped to the script.
.OUTPUTS
If $VMHost is piped in, returns a PSCustomObject for each piece of CDP info.
If $VMHost is passed as a parameter, returns a single formated table with all the CDP info.
.EXAMPLE
Running directly the script. Connection information will be prompted when needed.
PS> .\Get-CDP.ps1
.EXAMPLE
Connect first to any VIServer and pipe the result returned from Get-VMHost.
PS> Connect-VIServer xxx -User xxx -Password xxx
PS> Get-VMHost -Name abc* | .\Get-CDP.ps1
.EXAMPLE
Piping host names to the script or passing them as parameter.
The first command with Sort-Object and Format-Table is equivalent to the second one.
PS> 'esx1.example.com','esx2.example.com' | .\Get-CDP.ps1 | Sort-Object -Property VMHost,VMNic | Format-Table -AutoSize
PS> .\Get-CDP.ps1 -VMHost 'esx1.example.com','esx2.example.com'
#>
param(
[Parameter(ValueFromPipeline, Mandatory = $true)]
[object[]]$VMHost
)
Begin {
# make sure a VIServer is connected
while ($null -eq $global:defaultviserver) {
$viServer = Read-Host -Prompt "vCenter / ESXi host to connect to"
Connect-VIServer -Server $viServer > $null
}
function getCdp {
param ($hostObj)
# check for invalid host object
if ($null -eq $hostObj) {
Write-Host ("Host object is null.")
return
}
if ($hostObj -is [string]) {
Write-Progress -Activity ("Host: " + $hostObj) -Status "Getting HostSystem object..."
$vmhostview = Get-View -ViewType HostSystem -Filter @{"Name"=$hostObj} -Property "Name","ConfigManager.NetworkSystem"
}
if ($hostObj -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl]) {
Write-Progress -Activity ("Host: " + $hostObj.Name) -Status "Getting HostSystem object..."
$vmhostview = Get-View -VIObject $hostObj -Property "Name","ConfigManager.NetworkSystem"
}
if (($null -eq $vmhostview) -or
($vmhostview -isnot [VMware.Vim.HostSystem])) {
Write-Host ("Invalid host object " + $hostObj + ".")
return
}
# get CDP info
$esxname = $vmhostview.Name
Write-Progress -Activity ("Host: " + $esxname) -Status "Getting CDP information..." -PercentComplete 0
#Write-Host ("Getting CDP data from " + $esxname + "...")
$nsview = Get-View $vmhostview.ConfigManager.NetworkSystem
for ($i = 0; $i -lt $nsview.NetworkInfo.Pnic.Length; $i++) {#foreach ($physnic in $nsview.NetworkInfo.Pnic) {
$physnic = $nsview.NetworkInfo.Pnic[$i]
$DevId = $null
$Address = $null
$PortId = $null
$vLan = $null
$LinkSpeed_Mb = $physnic.LinkSpeed.SpeedMb
$pnicInfo = $nsview.QueryNetworkHint($physnic.Device)
foreach ( $hint in $pnicInfo ) {
$csp = $hint.ConnectedSwitchPort
if ($csp) {
$DevId = $csp.DevId
$Address = $csp.Address
$PortId = $csp.PortId
$vLan = $csp.vLan
}
$csp = $null
}
[PSCustomObject]@{
VMHost = $esxname;
VMNic = $physnic.Device;
LinkSpeed_Mb = $LinkSpeed_Mb;
DevId = $DevId;
Address = $Address;
PortId = $PortId;
vLan = $vLan
} | Write-Output
Write-Progress -Activity ("Host: " + $esxname) -Status "Getting CDP information..." -PercentComplete (($i+1) / $nsview.NetworkInfo.Pnic.Length * 100)
}
}
}
Process {
# when piped, $_ != $null and $_ == $VMHost[0]; $VMHost is an array with 1 element.
# when run directly, $_ == $null; $VMHost is an array with all elements.
if ($MyInvocation.ExpectingInput) {
# pass the cdp object directly when in a pipeline
getCdp $_
}
else { # direct parameter
$VMHost | ForEach-Object {
getCdp $_
} | Sort-Object -Property VMHost,VMNic | Format-Table -AutoSize
}
}
End {
}
# param(
# [Parameter(ValueFromPipeline, Mandatory = $true)]
# [object[]]$VMHost
# )
# make sure a VIServer is connected
while ($null -eq $global:DefaultVIServer) {
$viStr = Read-Host -Prompt "vCenter / ESXi host to connect to"
Connect-VIServer -Server $viStr > $null
}
# run on default servers
$view = Get-View -ViewType HostSystem -Property 'Name',
'Summary.OverallStatus',
'Summary.Runtime.PowerState',
'Summary.QuickStats.Uptime',
'Summary.QuickStats.OverallCpuUsage',
'Summary.QuickStats.OverallMemoryUsage',
'Summary.Hardware.CpuMhz',
'Summary.Hardware.NumCpuCores',
'Summary.Hardware.MemorySize',
'Summary.Hardware.OtherIdentifyingInfo'
$view | Sort-Object -Property 'Name' | Format-Table -Property 'Name',
@{label='Status'; e={ $_.Summary.OverallStatus }},
@{label='PowerState'; e={ $_.Summary.Runtime.PowerState }},
@{label='Up Time'; e={ '{0:0.#} days' -f ($_.Summary.QuickStats.Uptime / 86400) }},
@{label='CPU Usage'; e={ if (($_.Summary.QuickStats.OverallCpuUsage, $_.Summary.Hardware.CpuMhz, $_.Summary.Hardware.NumCpuCores).Contains($null))
{'unknown'}
else
{ '{0:f0}%' -f ($_.Summary.QuickStats.OverallCpuUsage / $_.Summary.Hardware.CpuMhz / $_.Summary.Hardware.NumCpuCores * 100) }}},
@{label='Memory Usage'; e={ if (($_.Summary.QuickStats.OverallMemoryUsage, $_.Summary.Hardware.MemorySize).Contains($null))
{'unknown'}
else
{ '{0:f0}%' -f ($_.Summary.QuickStats.OverallMemoryUsage / $_.Summary.Hardware.MemorySize * 104857600) }}},
@{label='Service Tag'; e={ $_.Summary.Hardware.OtherIdentifyingInfo[1].IdentifierValue }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment