Для работы с SNMP необходимо подключить модуль SharpSNMP.
Из неожиданностей
- в OID MAC адреса хранятся в десятичном формате, пришлось их переводить в шестнадцатеричный.
- Простым способом вернуть несколько значений из функции невозможно. Пришлось городить хэш-таблицу, в которой хранились бы три массива (MAC, vlan, port)
В OID информация хранится следующим образом:
OID Data
--- ----
.1.3.6.1.2.1.17.7.1.2.1.1.2.1 223
.1.3.6.1.2.1.17.7.1.2.1.1.2.41 63
.1.3.6.1.2.1.17.7.1.2.1.1.2.4026 222
.1.3.6.1.2.1.17.7.1.2.2.1.2.1.144.2.166.50.206.43 3
.1.3.6.1.2.1.17.7.1.2.2.1.2.1.144.2.166.50.206.63 6
.1.3.6.1.2.1.17.7.1.2.2.1.2.1.144.2.166.50.206.126 4
.1.3.6.1.2.1.17.7.1.2.2.1.2.41.0.21.100.59.187.78 26
.1.3.6.1.2.1.17.7.1.2.2.1.2.4026.0.9.136.173.129.150 26
.1.3.6.1.2.1.17.7.1.2.2.1.3.4026.232.64.241.24.239.215 3
.1.3.6.1.2.1.17.7.1.2.2.1.3.4026.232.64.241.24.242.213 3
Первые три строки (может быть больше или меньше, в зависиомсти от количества vlan'ов): последняя цифра - номер vlan'а, data - количество MAC-адресов в этом влане в FDB-таблице.
Далее следуют строки с перечислением MAC-адресов, сгруппированные по vlan'ам: после символов .1.3.6.1.2.1.17.7.1.2.2.1.2. идет номер vlan (1, 41, 4026 в нашем случае), а за ним MAC адрес в десятичном формате. В поле Data - порт с найденным MAC-ом.
Далее следуют строки, начинающиеся на .1.3.6.1.2.1.17.7.1.2.2.1.3. Они содержат информацию, о способе получения MAC-адреса. Если параметр 3 - MAC получен методом learning (опрос порта), 4 - MAC коммутатора, с которого взяли FDB.
Мы будем обрабатывать строки из второго блока. Сначала отсекаем ненужную нам часть OID, затем разбиваем на подстроки и запоминаем данные. Полученные данные выводим по порядку в 3 массива - MAC, port, vlan.
Собственно скрипт:
function findonswitch ([string]$ip) {
$oid=".1.3.6.1.2.1.17.7.1.2.2.1.2."
$mas = Invoke-SnmpWalk $ip ".1.3.6.1.2.1.17.7.1.2" #vlans
$i=0
$vlan=@()
$mac=@()
$port=@()
foreach ($pt in $mas)
{
if ($pt.OID -like "*$oid*")
{
$pt.OID = $pt.OID.remove(0,28)
$vlan += $pt.OID.Substring(0, $pt.OID.IndexOf("."))
$temp = $pt.OID.Substring($pt.OID.IndexOf(".") + 1, $pt.OID.Length - $pt.OID.IndexOf(".")-1)
###перевод из Dec в Hex
$mas=$temp.split(".")
$nmac=@()
foreach ($sdec in $mas)
{
$dec = [int]$sdec
$nmac += '{0:X2}' -f $dec
}
$str=$nmac -join "-"
###
$mac += $str
$port += $pt.Data
}
}
$return= @{}
$return.vlan=$vlan
$return.mac=$mac
$return.port=$port
return $return
}
####################################################################
$rootIP = "192.168.0.21"
$sport = ("1", "2", "5", "12", "13", "14", "43", "44", "65", "66", "74", "107")
$swDB = ("192.168.0.42", "192.168.0.44", "192.168.0.61", "192.168.0.52", "192.168.0.51", "192.168.0.12", "192.168.0.33", "192.168.0.32", "192.168.0.41", "192.168.0.43", "192.168.0.11", "192.168.0.34")
function findinarr ($array, $value) {
for ($i=0; $i -lt $array.count;$i++) {
if($array[$i] -eq $value){$i}
}
}
$res=findonswitch $rootIP
$dataMACRoot = $res.mac
$dataPortRoot = $res.port
$dataVlanRoot = $res.vlan
$mac = Read-Host "Enter MAC"
if ($mac.indexof(":") -ne 0)
{
$mac=$mac.replace(":", "-")
}
$i=0
$flag=0
foreach ($S in $dataMACRoot)
{
if ($mac -eq $s)
{
$portRoot = $dataPortRoot[$i]
$vlanRoot = $dataVlanRoot[$i]
Write-Host $mac on $portRoot 'in vlan' $vlanRoot on RootSwitch
if ($flag -eq 0)
{
$portRoot1 = $dataPortRoot[$i]
}
$flag++
}
$i++
}
$A = findinarr $sport $portRoot1
$res=findonswitch $swDB[$A]
$dataMAC = $res.mac
$dataPort = $res.port
$dataVlan = $res.vlan
$i=0
foreach ($S in $dataMAC)
{
if ($mac -eq $s)
{
$port = $dataPort[$i]
$vlan = $dataVlan[$i]
Write-Host $mac on $port 'in vlan' $vlan on 'switch' $swDB[$A]
}
$i++
}
Работа второй части скрипта (после ###########) описана в предыдущем посте. Тут она претерпела некоторые изменения, в связи с входящей информацией из массива, а не из csv-файла, но логика не изменилась.
Комментариев нет:
Отправить комментарий
Примечание. Отправлять комментарии могут только участники этого блога.