Powershell: преобразование выходных данных строки октетов (SNMP) в шестнадцатеричные (адрес Mac)
Поэтому я кратко объясню ENV: необходимо работать на сервере Win2k8 с Powershell 4.0
Я хочу получить некоторую информацию по SNMP (например, тип принтера и MAC-адрес принтера):
$SNMP = new-object -ComObject olePrn.OleSNMP
$SNMP.open($P_IP,"public",2,3000)
$PType = $SNMP.get(".1.3.6.1.2.1.25.3.2.1.3.1")
$PMac = $SNMP.get(".1.3.6.1.2.1.2.2.1.6.2")
echo $PType
echo $PMac
Итак, вывод выглядит так (как пример):
$ PType = принтер HP Officejet Pro 251dw
$PMac = ÓÁÔ*
Итак, прежде всего я начал проверять, использовал ли я правильный OID - используя инструмент командной строки SnmpSoft Company. Там результат выглядел хорошо:
OID = OID =.1.3.6.1.2.1.2.2.1.6.2
Тип =OctetString
Значение = A0 D3 C1 D4 2A 95 ....*.
Итак, я начал проверять, какой тип данных имеет это значение OID: Это строка октетов. На следующих шагах я начал искать возможности, как преобразовать это строковое значение октета в некоторый читаемый гекс - до сих пор без какой-либо прогрессии. я попытался преобразовать его в байты следующим образом:
$bytes = [System.Text.Encoding]::Unicode.GetBytes($PMac)
[System.Text.Encoding]::ASCII.GetString($bytes)
echo $bytes
Но вывод меня просто смущает
160 0 211 0 193 0 212 0 42 0 34 32
Попытка интерпретировать этот вывод без какого-либо успеха. Google больше не может мне помочь, потому что я тоже не понимаю медленно, как и что искать.
Так что вот я и надеюсь получить некоторую помощь или совет, как я могу изменить вывод этого запроса на что-то удобочитаемое.
2 ответа
Это проблема кодирования.
1.3.6.1.2.1.2.2.1.6 - физический адрес интерфейса. Поэтому я ожидаю, что значением будет MAC-адрес интерфейса. Результат вашей командной строки начинается с A0-D3-C1, который является диапазоном MAC-адресов HP, поэтому он соответствует. MAC-адрес вашего принтера должен быть A0 D3 C1 D4 2A 95? Вы не заявили об этом, поэтому вы оставляете меня угадывать.
Я подозреваю что $PMac
должен быть [byte[]]
(байтовый массив), но вывод преобразует его в строку, а система вывода PowerShell интерпретирует его как символы.
Пример:
PS C:\> [byte[]]$bytes = 0xa0, 0xd3, 0xc1, 0xd4, 0x2a, 0x95
PS C:\> [System.Text.Encoding]::Default.GetString($bytes)
ÓÁÔ*•
Вам, вероятно, нужно сделать что-то вроде этого:
$MAC = [System.Text.Encoding]::Default.GetBytes($PMac) | ForEach-Object {
$_.ToString('X2')
}
$MAC = $MAC -join '-'
Вы можете использовать [System.Text.Encoding]::ASCII.GetBytes($PMac)
вместо этого, поскольку необработанный SNMP должен использовать кодировку ASCII. Я понятия не имею, что использует olePrn.OleSNMP.
Вы также можете посмотреть на один из модулей SNMP PowerShell в галерее PowerShell. Это будет намного проще, чем иметь дело с COM-объектом в PowerShell.
Я также наткнулся на эту страницу по обработке SNMPOCTET STRING
, #SNMP - это библиотека.Net SNMP, и OCTET STRING
похоже, что это базовый тип для этого OID. На странице описаны некоторые трудности работы с этим конкретным типом объекта с помощью.Net. Вы также можете использовать эту библиотеку для разработки своих собственных командлетов в PowerShell; это доступно через NuGet.
Вывод, который вы получили, почти соответствует вашему ожидаемому MAC-адресу
160 0 211 0 193 0 212 0 42 0 34 32
160
десятичное для шестнадцатеричного 0xA0
211
является 0xD3
193
является 0xC1
Дополнительные нули между каждым байтом могут быть добавлены во время вызова Unicode.GetBytes, который я не думаю, что вам нужно будет использовать.
Я подозреваю, что вам нужно прочитать $PMac
в качестве массива байтов, затем выполните шестнадцатеричное преобразование строки для каждого байта. Это, вероятно, не самый элегантный, но может сделать работу:
[byte[]] $arrayofBytes = @(160,211,193)
[string] $hexString
foreach ($b in $arrayofBytes) {
$HexString += [convert]::toString($b,16)
$HexString += ' '
}