Powershell: Translate Octet String (SNMP) Output to Hex (Mac address)

5.4k views Asked by At

So i will shortly explain the env: Need to work on a Win2k8 Server with Powershell 4.0

I want to get some information with using SNMP (so printer type and printer MAC address):

$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

So, the Output looks like this (as an example):

$PType = HP Officejet Pro 251dw Printer

$PMac =  ÓÁÔ*

So, first of all i started to check, if i used the right OID - using the command line tool of SnmpSoft Company. There, the output looked well:

OID= OID=.1.3.6.1.2.1.2.2.1.6.2

Type=OctetString

Value= A0 D3 C1 D4 2A 95 ....*.

Alright, so i started to check, what kind of datatype this OID value have: It's octet string. In the next steps, i started to search for possibilities, how to transform this octet string value to some readable hex - until now without any progression. i tried to transform it into Bytes this way:

$bytes = [System.Text.Encoding]::Unicode.GetBytes($PMac) 
[System.Text.Encoding]::ASCII.GetString($bytes)
echo $bytes

But the output just confusing me

160 0 211 0 193 0 212 0 42 0 34 32

Tryed to interpret this output without any success. Google can't help me anymore because i don't understand slowly also, how or what to search.

So here i am and hoping to get some help or an advice, how i can change the output of this query to something readable.

2

There are 2 answers

0
veefu On

The output you got is very nearly your expected MAC address

160 0 211 0 193 0 212 0 42 0 34 32

160 is decimal for hexadecimal 0xA0

211 is 0xD3

193 is 0xC1

The additional zeros between each byte may have been added during the Unicode.GetBytes call, which I don't think you'll need to use.

I suspect you'll need to read $PMac as an array of bytes, then do hexadecimal string conversion for each byte. This is probably not the most elegant, but may get the job done:

[byte[]] $arrayofBytes = @(160,211,193)

[string] $hexString
foreach ($b in $arrayofBytes) {
    $HexString += [convert]::toString($b,16)
    $HexString += ' '
}
0
Bacon Bits On

It's an encoding problem.

1.3.6.1.2.1.2.2.1.6 is the interface physical address. So I would expect the value to be the MAC address of the interface. Your command line result begins with A0-D3-C1, which is an HP MAC address range, so it's consistent. Your printers MAC address must be A0 D3 C1 D4 2A 95? You didn't state that, so you're leaving me to guess.

I suspect that $PMac is supposed to be a [byte[]] (byte array), but the output is converting it to a string and PowerShell's output system is interpreting it as characters.

Example:

PS C:\> [byte[]]$bytes = 0xa0, 0xd3, 0xc1, 0xd4, 0x2a, 0x95
PS C:\> [System.Text.Encoding]::Default.GetString($bytes)
 ÓÁÔ*•

You probably need to do something like this:

$MAC = [System.Text.Encoding]::Default.GetBytes($PMac) | ForEach-Object {
    $_.ToString('X2')
}
$MAC = $MAC -join '-'

You may want to use [System.Text.Encoding]::ASCII.GetBytes($PMac) instead, since raw SNMP is supposed to use ASCII encoding. I've no idea what olePrn.OleSNMP uses.

You might also look at one of the SNMP PowerShell modules on the PowerShell Gallery. That will be much easier than dealing with COM object in PowerShell.

I also came across this page on #SNMP's handling of OCTET STRING. #SNMP is a .Net SNMP library, and OCTET STRING appears to be what the underlying type is for this OID. The page describes some of the difficulties of working with this particular object type with .Net. You could also use this library for developing your own Cmdlets in PowerShell; it's available through NuGet.