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 += ' '
}
Другие вопросы по тегам