在为我的网络创建审计工具时,我发现 WMIC 在输出常规文本时,每个字符之间都会有空格。例如,
这:
@echo off
echo Foo >> "C:\test.txt"
wmic CPU Get AddressWidth >> "C:\test.txt"
wmic CPU Get Description >> "C:\test.txt"
返回此:
Foo
A d d r e s s W i d t h
6 4
D e s c r i p t i o n
I n t e l 6 4 F a m i l y 6 M o d e l 6 9 S t e p p i n g 1
如果我删除(rem
)该echo Foo
行,则输出格式很好,因为只有一种输出类型:
AddressWidth
64
Description
Intel64 Family 6 Model 69 Stepping 1
我读到这是因为 WMIC 输出为 UNICODE,而标准批处理命令输出为 ANSI。两者可以合并以共享通用格式吗?有人可以更深入地解释不同的格式类型、为什么 WMIC 会输出为不同的类型以及/或导致此输出的任何其他因素吗?我发现了一些面包屑,但没有具体内容。
答案1
Wmic
通过管道传输输出more
:
wmic CPU Get AddressWidth |more >> "C:\test.txt"
编辑以获取更多背景信息:您看到的问题是由于wmic
输出是 unicode utf-16 造成的。这意味着每个字符(或者更准确地说,大多数字符)都用两个字节编码。wmic
还会在输出的开头放置一个所谓的 BOM(字节顺序标记)。请参阅下面的字节内容:
FF FE 44 00 65 00 73 00-63 00 72 00 69 00 70 00 ..D.e.s.c.r.i.p.
前两个字节 (FF FE) 指定 UTF-16 的字节顺序,并允许数据处理工具识别编码 [UTF-16 小端字节序]。
显然,type
它会进行此检查,如果找到 BOM,则正确识别编码。
另一方面,如果你第一的 echo text
然后附加Wmic
输出 - 开头没有 BOM,并且您可以看到不一致的编码:
74 65 78 74 20 0D 0A 44-00 65 00 73 00 63 00 72 text ..D.e.s.c.r
如果您将它通过,type
它就无法推断如何解释,/最有可能/假设单字节('ANSI')并且这会导致为不可打印字符产生空格(零,实际上是双字节字符编码的高位字节)。
more
处理更多(双关语)情况并为基本 ASCII 字符生成正确的输出,这就是为什么它通常用作此目的的黑客攻击。
补充一点:如果文件一致,某些编辑器(记事本是最简单的例子)将正确显示 utf-16 编码文件 - 即使没有 BOM。有一种方法可以强制echo
生成 unicode 输出(但请注意它不会生成 BOM)- 使用cmd /u
导致输出内部命令是unicode。
我真的说不出为什么 cmd unicode 支持如此有限(或者像大多数人会说的那样 - 损坏了...) - 可能是历史/兼容性问题。
最后一件事 - 如果你需要更好的unicode支持(以及许多其他好处),我建议迁移到powershell
答案2
该more
命令似乎不能很好地完成转换。请注意 x2.txt 输出文件中的双 CR (\r)。
C:>wmic diskdrive where "model = 'HGST HTS725050A7E630 ATA Device'" get index >x1.txt
C:>wmic diskdrive where "model = 'HGST HTS725050A7E630 ATA Device'" get index | more >x2.txt
C:>odd x1.txt
000000 ff fe 49 00 6e 00 64 00 65 00 78 00 20 00 20 00
377 376 I \0 n \0 d \0 e \0 x \0 \0 \0
000010 0d 00 0a 00 30 00 20 00 20 00 20 00 20 00 20 00
\r \0 \n \0 0 \0 \0 \0 \0 \0 \0
000020 20 00 0d 00 0a 00
\0 \r \0 \n \0
000026
C:>odd x2.txt
000000 49 6e 64 65 78 20 20 0d 0d 0a 30 20 20 20 20 20
I n d e x \r \r \n 0
000010 20 0d 0d 0a 0d 0d 0a 0d 0a
\r \r \n \r \r \n \r \n
更新 看起来 PowerShell 可以更好地处理这个问题。
Get-WmiObject Win32_diskdrive |
Where-Object { $_.Model -like '*WD*' } |
Select-Object -Property Model |
Out-File -PSPath t1.txt
Get-WmiObject Win32_diskdrive |
Where-Object { $_.Model -like '*WD*' } |
Select-Object -Property Model |
Out-File -PSPath t2.txt -Encoding default
很明显,CIM 是 PowerShell 未来的发展方向。最好现在就开始使用它。
Get-CimInstance CIM_DiskDrive |
Where-Object { $_.Model -like '*WD*' } |
Select-Object -Property Model |
Out-File -PSPath t1.txt
Get-CimInstance CIM_DiskDrive |
Where-Object { $_.Model -like '*WD*' } |
Select-Object -Property Model |
Out-File -PSPath t2.txt -Encoding default
答案3
如果我们只需要让 WMIC 将其数据添加到日志文件,请尝试以下操作:
测试脚本
set Log=%~dpn0.log&::
set L=^>^>"%Log%" 2^>^&1 echo&::
%L% ^
wmic /APPEND:"%Log%" /locale:ms_409 service get name,startname,state,status&::
wmic /APPEND:"%Log%" /locale:ms_409 service get name,startname,state,status&::
notepad "%Log%"
exit
生成的 Test.log 文件将如下所示:
wmic /APPEND:"D:\Test\T.log" /locale:ms_409 service get name,startname,state,status
Name StartName State Status
AdobeARMservice LocalSystem Running OK
AJRouter NT AUTHORITY\LocalService Stopped OK
ALG NT AUTHORITY\LocalService Stopped OK
AppHostSvc LocalSystem Running OK
AppIDSvc NT Authority\LocalService Stopped OK
答案4
参考这个答案:WMIC.bat 文件无法正确导出/输出
More
此批处理文件向您展示了使用和不使用命令将结果导出到文本文件的行为的区别。
@echo off
REM https://stackoverflow.com/questions/34075745/wmic-bat-file-will-not-export-output-properly?answertab=active#tab-top
Title WMIC file will not export/output properly
set "WithoutMore=%~dp0WithoutMore.txt"
set "WithMore=%~dp0WithMore.txt"
(
wmic csproduct
wmic cpu get name,AddressWidth,Description
wmic diskdrive get model,size
WMIC PATH Win32_Battery Get EstimatedChargeRemaining
ipconfig /all
)>"%WithoutMore%"
Start "" "%WithoutMore%"
(
wmic csproduct
wmic cpu get name,AddressWidth,Description
wmic diskdrive get model,size
WMIC PATH Win32_Battery Get EstimatedChargeRemaining
ipconfig /all
) | more >"%WithMore%"
Start "" "%WithMore%"