Reputation: 10764
Consider the following PowerShell code:
$SNMP = New-Object -COMObject OLEPrn.OLESNMP
$SNMP.Open("10.178.230.105", "public", 2, 3000)
$MACAddress = $SNMP.Get(".1.3.6.1.2.1.2.2.1.6.1")
$SNMP.Close()
At this point, $MACAddress
is supposed to contain a six-byte string, which when decoded to hex, should be the MAC Address of the printer. This is a Xerox printer, and the first two bytes are supposed to be 0x9C 0x93
. However,
for ($i = 0; $i -lt 6; $i++) {
"{0}: {1:X2}" -f $MACAddress[$i],[BYTE]$MACAddress[$i]
}
throws an error for the first two bytes:
Cannot convert value "œ" to type "System.Byte". Error: "Value was either too large or too small for an unsigned byte."
At Z:\Scripts\Powershell\SNMPscratch.ps1:10 char:4
+ "{0}: {1:X2}" -f $MACAddress[$i],[BYTE]$MACAddress[$i]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastIConvertible
Cannot convert value "“" to type "System.Byte". Error: "Value was either too large or too small for an unsigned byte."
At Z:\Scripts\Powershell\SNMPscratch.ps1:10 char:4
+ "{0}: {1:X2}" -f $MACAddress[$i],[BYTE]$MACAddress[$i]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastIConvertible
N: 4E
s: 73
-: 2D
|: 7C
(The last four bytes are correctly converted.)
If I cast to an [int]
instead, and make the field for the hex value four characters instead:
for ($i = 0; $i -lt 6; $i++) {
"{0}: {1:X4}" -f $MACAddress[$i],[int]$MACAddress[$i]
}
I get no error, but...
œ: 0153
“: 201C
N: 004E
s: 0073
-: 002D
|: 007C
... where the first two "bytes" are not 0x9C 0x93
, the way they're supposed to be.
What's going wrong, where, and how do I fix it or work around it?
Supplemental information:
I thought that perhaps the encoding was the problem, and tried
[byte[]]$MACAddress = ([System.Text.Encoding]::ASCII).GetBytes($SNMP.Get(".1.3.6.1.2.1.2.2.1.6.1"))
which avoided throwing the error, but generated
63: 003F
63: 003F
78: 004E
115: 0073
45: 002D
124: 007C
which is also wrong - but this makes it look like the problem may be in $SNMP.Get()
, rather than in anything I'm doing. If so, is there any alternative, short of using a third-party library, which our Information Security people will not approve?
Upvotes: 4
Views: 2485
Reputation: 27428
This works for me, "[System.Text.Encoding]::Default.GetBytes()". Although if the mac address begins with a 0, .Get() returns an empty string. There's always an old version of the Net-SNMP snmpwalk windows binary.
# snmpmac.ps1
param($PrinterAddress)
$oid = '.1.3.6.1.2.1.2.2.1.6.1' # mac address
$SNMP = New-Object -ComObject olePrn.OleSNMP
foreach($printer in $PrinterAddress) {
$SNMP.Open($Printer, "public", 2, 3000)
$string = $SNMP.Get($oid)
$MacAddress = ([System.Text.Encoding]::Default.GetBytes($string) |
% tostring X2) -join '-'
[pscustomobject]@{Name = $Printer; MacAddress = $MacAddress}
$SNMP.Close()
}
.\snmpmac a-cp2,a-mfp1,a-mfp2,a-mfp3,a-mfp4
Name MacAddress
---- ----------
a-cp2
a-mfp1 58-38-79-23-AE-54
a-mfp2 58-38-79-23-AD-E8
a-mfp3 58-38-79-23-AE-70
a-mfp4 58-38-79-23-B0-B0
Upvotes: 2
Reputation: 63143
You made a few incorrect statements.
First, Xerox reserves 9C:93:4E
, so checking the first two bytes 9C:93
is not enough. Reference
Second, 3F:3F:4E
is valid, and is locally administered MAC address, assigned to a device by an administrator. Such addresses do not contain OUIs for vendor recognition.
Guess this device probably has multiple NICs, so you should make a WALK operation to check all NICs, and don't blindly go to the very first in the table.
Upvotes: 1