考虑以下 PowerShell 代码:
$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()
此时,
$MACAddress
应该包含一个六字节字符串,当解码为十六进制时,它应该是打印机的MAC地址。这是一台 Xerox 打印机,前两个字节应该是 0x9C 0x93
。然而,
for ($i = 0; $i -lt 6; $i++) {
"{0}: {1:X2}" -f $MACAddress[$i],[BYTE]$MACAddress[$i]
}
前两个字节抛出错误:
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
(最后四个字节已正确转换。)
如果我改为转换为
[int]
,并将十六进制值字段设置为四个字符:
for ($i = 0; $i -lt 6; $i++) {
"{0}: {1:X4}" -f $MACAddress[$i],[int]$MACAddress[$i]
}
我没有收到错误,但是...
œ: 0153
“: 201C
N: 004E
s: 0073
-: 002D
|: 007C
...前两个“字节”是 not
0x9C 0x93
,它们应该是这样的。
出了什么问题、出在哪里以及如何修复或解决它?
补充信息:
我认为可能是编码问题,并尝试了
[byte[]]$MACAddress = ([System.Text.Encoding]::ASCII).GetBytes($SNMP.Get(".1.3.6.1.2.1.2.2.1.6.1"))
这避免了抛出错误,但生成了
63: 003F
63: 003F
78: 004E
115: 0073
45: 002D
124: 007C
这也是错误的——但这使得问题看起来可能出现在
$SNMP.Get()
中,而不是出现在我正在做的任何事情中。如果是这样,除了使用第三方库之外,还有其他选择吗?我们的信息安全人员会不批准?
这对我有用,“[System.Text.Encoding]::Default.GetBytes()”。尽管如果 mac 地址以 0 开头,.Get() 返回一个空字符串。始终存在旧版本的 Net-SNMP snmpwalk Windows 二进制文件。
# 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
你做了一些不正确的陈述。
首先,Xerox 保留
9C:93:4E
,因此检查前两个字节 9C:93
是不够的。 参考
其次,
3F:3F:4E
有效,并且是本地管理的 MAC 地址,由管理员分配给设备。此类地址不包含用于供应商识别的 OUI。
猜测这个设备可能有多个网卡,所以你应该进行WALK操作来检查所有网卡,不要盲目地走到表中的第一个。
看起来 olePrn.OleSNMP 无法获取以 00 开头的任何内容。可以单独使用 PowerShell 解决这个问题吗?