4

При создании инструмента аудита для моей сети я обнаружил, что 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 будет выводить данные другого типа и / или какие-либо другие факторы, влияющие на этот результат? Я нашел несколько хлебных крошек, но ничего конкретного.

3 ответа3

8

Труба выход из 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 выполняет эту проверку, и если он находит спецификацию, то правильно распознает кодировку.
С другой стороны, если вы сначала выводите echo text а затем добавляете вывод Wmic - в начале нет спецификации, и вы можете увидеть несогласованную кодировку:
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, если он согласован - даже без спецификации. Есть способ заставить echo генерировать вывод Unicode (но будьте осторожны, он не генерирует BOM) - использование cmd /u приводит к выводу Unicode для внутренних команд .

Я не могу точно сказать, почему поддержка Unicode в CMD настолько ограничена (или, как многие сказали бы, нарушена ...) - возможно, проблемы с историей / совместимостью.

И последнее - если вам нужна лучшая поддержка юникода (среди многих других преимуществ), я бы порекомендовал перейти на powershell

2

Команда more , по-видимому, плохо выполняет преобразование. Обратите внимание на двойной CR (\r) в выходном файле x2.txt.

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
0

Если нам нужно только получить WMIC для добавления своих данных в файл журнала, попробуйте следующее:

Test.bat

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      

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .