Powershell:将八位字节字符串 (SNMP) 输出转换为十六进制(Mac 地址)

Posted

技术标签:

【中文标题】Powershell:将八位字节字符串 (SNMP) 输出转换为十六进制(Mac 地址)【英文标题】:Powershell: Translate Octet String (SNMP) Output to Hex (Mac address) 【发布时间】:2018-02-12 14:24:27 【问题描述】:

所以我将简短地解释一下环境: 需要在装有 Powershell 4.0 的 Win2k8 服务器上工作

我想使用 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 公司的命令行工具。在那里,输出看起来不错:

OID= OID=.1.3.6.1.2.1.2.2.1.6.2

Type=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 不能再帮助我了,因为我也慢慢不明白如何搜索或搜索什么。

所以我在这里,希望得到一些帮助或建议,我如何将此查询的输出更改为可读的内容。

【问题讨论】:

$PMac.GetType() 的输出是什么? 【参考方案1】:

这是一个编码问题。

1.3.6.1.2.1.2.2.1.6 is the interface physical address。所以我希望该值是接口的 MAC 地址。您的命令行结果以 A0-D3-C1 开头,即HP MAC address range,因此是一致的。您的打印机 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 modules on the PowerShell Gallery 之一。这将比在 PowerShell 中处理 COM 对象容易得多。

我也遇到了this page on #SNMP's handling of OCTET STRING。 #SNMP 是一个 .Net SNMP 库,OCTET STRING 似乎是此 OID 的基础类型。该页面描述了使用 .Net 处理这种特定对象类型的一些困难。您还可以使用此库在 PowerShell 中开发您自己的 Cmdlet; it's available through NuGet.

【讨论】:

【参考方案2】:

你得到的输出非常接近你预期的 MAC 地址

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

160 是十六进制的十进制 0xA0

2110xD3

1930xC1

在 Unicode.GetBytes 调用期间可能已在每个字节之间添加了额外的零,我认为您不需要使用它。

我怀疑您需要将$PMac 读取为字节数组,然后对每个字节进行十六进制字符串转换。这可能不是最优雅的,但可以完成工作:

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

[string] $hexString
foreach ($b in $arrayofBytes) 
    $HexString += [convert]::toString($b,16)
    $HexString += ' '

【讨论】:

以上是关于Powershell:将八位字节字符串 (SNMP) 输出转换为十六进制(Mac 地址)的主要内容,如果未能解决你的问题,请参考以下文章

Power BI 使用 DAX 将八位 yyyymmdd 转换为日期

将八位字节流转换为图像

八位字符串:它是啥?

在 std::string 中使用非法 UTF-8 八位字节作为分隔符

当我的 Perl 程序在 cmd.exe 中输出 UTF-8 编码字符串时,为啥我会重复最后一个八位字节?

python中的字符串和字节串