Public/Get-LinuxCdpInfo.ps1
function Get-LinuxCdpInfo { # Requires -Module Posh-SSH -Version 3.0 [CmdletBinding()] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true )] [string[]]$ComputerName, [Parameter()] [string[]]$Interface = 'eth0', [Parameter(Mandatory = $true)] [pscredential]$Credential, [parameter()] [int] $Concurrency = 8 ) begin { [System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseDeclaredVarsMoreThanAssigments', '')] $SessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() $RunspacePool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1, ($Concurrency + 1)) $RunspacePool.Open() $PowerShell = [powershell]::Create() $PowerShell.RunspacePool = $RunspacePool $Commands = New-Object -TypeName System.Collections.ArrayList $ScriptBlock = { param( [string]$ComputerName, [string]$Interface, [pscredential]$Credential ) $PortAbbreviation = @{ "FastEthernet" = "Fa " "GigabitEthernet" = "Gi " "TenGigabitEthernet" = "Te " } $InterfacesFromTcpdump = @() try { $SshSession = New-SSHSession -ComputerName $ComputerName -Credential $Credential -AcceptKey -Force $Result = Invoke-SSHCommand -SSHSession $SshSession -Command 'tcpdump -D' foreach ($Line in $Result.Output) { if ($Line -notmatch '^[0-9]+.usbmon') { $InterfacesFromTcpdump += $Line.Trim().Split('.')[1] } } Write-Debug -Message "Active interface list from tcpdump`n$($InterfacesFromTcpdump | Out-String)" foreach ($Filter in $Interface) { $IfaceList += $InterfacesFromTcpdump | Where-Object { $_ -like $Filter } Write-Debug -Message "Interfaces matching filter $($Filter):`n$($IfaceList | Out-String)" } foreach ($Iface in $IfaceList) { $Command = "tcpdump -i $Iface -v -nn -s 1500 -c 1 -G 60 'ether[20:2] == 0x2000'" $Result = Invoke-SSHCommand -SSHSession $SshSession -Command $Command Write-Debug -Message ($Result.Output | Out-String) $NativeVlan = ($Result.Output | Where-Object { $_ -match '\(0x0a\)' }).ToString().Split(' ')[-1] -replace ("'", "") $PortName = ($Result.Output | Where-Object { $_ -match '\(0x03\)' }).ToString().Split(' ')[-1] -replace ("'", "") $PortAbbreviation.GetEnumerator() | ForEach-Object { $PortName = $PortName.Replace($_.Name, $_.Value) } $SwitchAdress = ($Result.Output | Where-Object { $_ -match '\(0x02\)' }).ToString().Split(' ')[-1] -replace ("'", "") $SwitchName = ($Result.Output | Where-Object { $_ -match '\(0x01\)' }).ToString().Split(' ')[-1] -replace ("'", "") $Output = New-Object -TypeName PSObject -Property @{ 'ComputerName' = $ComputerName 'Interface' = $Iface 'NativeVlan' = $NativeVlan 'PortName' = $PortName 'SwitchAddress' = $SwitchAdress 'SwitchName' = $SwitchName } $Output.PSObject.TypeNames.Insert(0, 'ServerManagement.CdpInfo') Write-Output -InputObject $Output } } catch { throw } finally { if ($SshSession) { $SshSession.Disconnect() $null = Remove-SSHSession $SshSession } } #finally } } process { if ($DebugPreference) { foreach ($Computer in $ComputerName) { & $ScriptBlock -ComputerName $Computer -Interface $Interface -Credential $Credential } } else { foreach ($Computer in $ComputerName) { if (Test-Connection -ComputerName $Computer -Count 1 -Quiet) { $PowerShellInstance = [powershell]::Create() $PowerShellInstance.RunspacePool = $RunspacePool [void]$PowerShellInstance.AddScript($ScriptBlock) [void]$PowerShellInstance.AddParameter('ComputerName', "$Computer") [void]$PowerShellInstance.AddParameter('Credential', $Credential) [void]$PowerShellInstance.AddParameter('Interface', "$Interface") [void]$PowerShellInstance.AddParameter('DebugPreference', $DebugPreference) [void]$PowerShellInstance.AddParameter('VerbosePreference', $VerbosePreference) $Handle = $PowerShellInstance.BeginInvoke() $Temp = '' | Select-Object -Property ComputerName, PowerShell, Handle $Temp.ComputerName = $Computer $Temp.PowerShell = $PowerShellInstance $Temp.Handle = $Handle [void]$Commands.Add($Temp) } else { Write-Warning -Message "Cannot connect to computer '$Computer', because it is offline." } } $JobCount = $Commands.Count while ($Commands) { Write-Progress -Activity "Querying CDP Information" -Status "$($Commands.Count) Remaining" -PercentComplete (($JobCount - $Commands.Count) / $JobCount * 100) foreach ($Command in $Commands.ToArray()) { if ($Command.Handle.IsCompleted -eq $true) { Write-Output -InputObject $Command.PowerShell.EndInvoke($Command.Handle) $Command.PowerShell.Dispose() $Commands.Remove($Command) } } Start-Sleep -Milliseconds 500 } } } end { $RunspacePool.Close() $RunspacePool.Dispose() } } |