2016-12-29 10 views
0

В настоящее время я пытаюсь заменить скрипт powershell скриптом cmd, поскольку он более подходит для того, что пытается сделать.Strip CMD output, чтобы просто показывать каталоги

В Powershell я использую этот кусок кода для получения списка личных каталогов папки на компьютере

$Name = [Environment]::UserName 
get-item HKCU:\software\Microsoft\Office\15.0\Outlook\Search\Catalog - ErrorAction SilentlyContinue | select -expandProperty property | Out-File Z:\global\pst\PowershellOutput\$Name.txt -append 

Это делает то, что я хочу, и выводит список каталогов, как так

H:\PST\My Outlook Data File 1.pst 
H:\PST\My Outlook Data File 2.pst 
C:\PST\My Outlook Data File 3.pst 

Однако, когда я запускаю эту строку, чтобы извлечь ключ реестра

regedit.exe /e Z:\global\battest\%username%.txt "HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog" 

Я получаю выход с большим количеством ненужных данных

Windows Registry Editor Version 5.00 

[HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog] 
"H:\\PST\\My Outlook Data File 1.pst"=hex:0c,01,00,00,00,00,00,00 
"H:\\PST\\My Outlook Data File 2.pst"=hex:f8,00,00,00,00,00,00,00 
"C:\\PST\\My Outlook Data File 3.pst"=hex:ac,02,00,00,00,00,00,00 

Эти данные передаются на другую программу * так обходным может использовать данные в пределах «» знаков, однако он также имеет двойную обратную косую черту, что делает данные неудобно проходить дальше.

Есть ли лучший способ захватить эти значения в CMD или, возможно, параметр, который я пропустил, который показывает каталоги?

  • -Извините не включать это раньше, однако эта программа не является программой CMD, это Visual Basic
+0

Проблема с 'regedit' это создает Unicode текстовые файлы по-умолчанию, которые не являются тривиальными для обработки с помощью' cmd'; поэтому используйте команду 'reg query' вместо ... – aschipfl

+0

Привет, могу спросить, почему cmd больше подходит для того, что пытается сделать, чем Powershell здесь? – sodawillow

+0

@sodawillow Если бы я использовал CMD вместо powershell, то для этого не нужно будет менять групповую политику. –

ответ

0

В то время как у меня нет офиса установлены для тестирования, это должно получить работу

@echo off 
    setlocal enableextensions disabledelayedexpansion 

    set "HKCU=&H80000001" 
    set "subKey=software\Microsoft\Office\15.0\Outlook\Search\Catalog" 

    >> "Z:\global\pst\PowershellOutput\%username%.txt" (
     for /f "tokens=2 delims={" %%a in (' 
      wmic 
       /NameSpace:\\root\default 
       Class StdRegProv 
       Call EnumValues 
        hDefKey^="%HKCU%" 
        sSubKeyName^="%subkey%" 
      2^>nul 
      ^| find "sNames = {" 
     ') do for %%b in (%%a) do (
      for /f delims^=^" %%c in ("%%~b") do echo(%%~fc 
     ) 
    ) 

wmic Он использует, чтобы получить список значений, определенных в соответствии с указанным ключом и фильтровать вывод только извлекать строка с именами этих значений в форме sNames = {"v1", "v2", "v3"}.

The { используется для разделения начала строки из списка значений (%%a), и этот список повторяется (%%b), чтобы получить каждое значение. Последний элемент в списке включает конец }, который необходимо удалить, это обрабатывается %%c, используя кавычки в значении как разделители.

Эквивалент версия VBS может быть

Option Explicit 

Const HKEY_CURRENT_USER = &H80000001 
Const ForAppending = 8 

Const SUB_KEY = "software\Microsoft\Office\15.0\Outlook\Search\Catalog" 
Const OUTPUT_PATH = "Z:\global\pst\PowershellOutput" 

Dim fso, shell 
    Set fso = WScript.CreateObject("Scripting.FileSystemObject") 
    Set shell = WScript.CreateObject("WScript.Shell") 

Dim values 
    Call GetObject(_ 
     "winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv" _ 
    ).EnumValues(_ 
     HKEY_CURRENT_USER, SUB_KEY, values _ 
    ) 

Dim outputFile 
    Set outputFile = fso.OpenTextFile(_ 
     fso.BuildPath(_ 
      OUTPUT_PATH, shell.ExpandEnvironmentStrings("%username%") & ".txt" _ 
     ) _ 
     , ForAppending _ 
     , True _ 
    ) 

Dim value  
    If Not IsNull(values) Then 
     For Each value In values 
      Call outputFile.WriteLine(fso.GetAbsolutePathName(value)) 
     Next 
    End If 

    Call outputFile.Close() 
+0

Большое спасибо за этот код, я не совсем понимаю его, но я достаточно понимаю, чтобы получить вывод в текстовый файл. Он по-прежнему отображает «\\» в каталогах, но это результат, с которым я могу жить. –

+0

Я просто хотел бы добавить это и сказать, что для получения вывода в текстовом файле все, что нужно, это '>> -InsertDirectory' в конце этой строки 'for/f delims^= ^" %% c in («%% ~ b») do echo (%% c' –

+0

@ J.Hodge, ответ обновлен, чтобы включить перенаправление в выходной файл, удаление двойного бара и версию vbs. –

0

Вы, вероятно, нужно использовать команду REG QUERY. В одном файле летучей мыши он хотел, как:

@echo OFF 
for /f "usebackq tokens=1-3" %%A in (`REG QUERY "HKCU\Software\Microsoft\Office\15.0\Outlook\Search\Catalog"`) do (
set ValueName=%%A 
) 
echo %ValueName% > Z:\global\battest\%username%.txt 

Получил это от How can I get the value of a registry key from within a batch script?

+0

Хорошо, я попытался запустить ваш бит кода, и это только дало мне один результат? –

+0

Извините, я не понимал, что ввод отправит комментарий. При некоторых поисках я придумал этот запрос: REG QUERY HKEY_CURRENT_USER \ Software \ Microsoft \ Office \ 15.0 \ Outlook \ Search \ Catalog/s | findstr/L ".pst"> \ "Z: \ global \ battest \% username% .txt", однако я не могу заставить это работать, поскольку он дает мне «недопустимый каталог». Я не уверен, почему ваш код (который я не совсем понимаю) дает мне только один результат. –

0

Вот пакетный код, чтобы получить список * .pst файлов (не каталогов), которые работают не зависит от числа файлов * .pst и их имен файлов, если имена файлов заканчиваются .pst.

@echo off 
setlocal EnableExtensions EnableDelayedExpansion 
for /F "skip=1 delims=" %%# in ('%SystemRoot%\System32\reg.exe query HKCU\Software\Microsoft\Office\15.0\Outlook\Search\Catalog 2^>nul') do (
    set "RegData=%%#" 
    set "DelData=!RegData:*.pst=!" 
    if not "!DelData!" == "!RegData!" call :OutputFileName 
) 
endlocal 
goto :EOF 

:OutputFileName 
set "RegData=!RegData:%DelData%=!" 
echo !RegData:~4! 
goto :EOF 

* .pst файлы Outlook, файлы Personal Storage, которые являются файлами контейнеры для электронной почты, контактов, ...

Команда ДЛЯ работает консольное приложение REG запросить все значения ключа реестра :

HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog 

выход на Windows Vista и более поздних версиях Windows, для примера:

HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog 
    H:\PST\My Outlook Data File 1.pst REG_SZ whatever the 
    H:\PST\My Outlook Data File 2.pst REG_SZ data value is 
    C:\PST\My Outlook Data File 3.pst REG_SZ of each value 

Выводится раздел реестра и следующие значения реестра, каждый из которых имеет 4 пробела и 4 пробела между именем значения и типом значения и 4 пробелами между типом значения и значением данных.

Но на Windows XP выход для примера:

! REG.EXE VERSION 3.0 

HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog 
    H:\PST\My Outlook Data File 1.pst REG_SZ whatever the 
    H:\PST\My Outlook Data File 2.pst REG_SZ data value is 
    C:\PST\My Outlook Data File 3.pst REG_SZ of each value 

Так есть первые две строки заголовка до ключа реестра. Значения реестра также имеют отступы с 4 пробелами.Но вместо пробелов между именем значения и типом значений есть 1 или более вкладок, а также вместо 1 и более табуляции вместо пробелов между типом значений и значением данных.

Примечание: Я не знаю, является ли REG_SZ правильным типом значения реестра. У меня нет этого раздела реестра вообще в моем реестре Windows, и поэтому просто добавил 3 значения реестра как строковые значения с фиктивными строками.

Таким образом, сложная часть заключается в том, как получить имя значения реестра, содержащее также пробелы, чтобы получить только имя файлов * .pst, независимых от имени файла.

Это делается путем присвоения каждой выходной линии, за исключением первой строки из skip=1 переменной окружения RegData и получить следующий из этой строки все после того, как .pst присвоенного переменной окружения DelData.

Если строка содержит .pst в любом случае вообще, что приводит к значению DelData быть не равно значение RegData, подпрограмма OutputFileName вызывается для дальнейшей обработки и печати имя файла * .pst файла.

В подпрограмме OutputFileName сначала строка справа от * .pst имя файла удаляется из RegData с помощью замены строки. Следующее * .pst имя файла выводится без 4 отступов в начале.

Если число отступов не всегда будет ровно 4 пробелами, то строка echo !RegData:~4! может быть заменена следующим кодом, чтобы работать независимо от количества отступов/вкладок.

for /F "tokens=1*" %%I in ("%RegData%") do (
    if "%%J" == "" (
     echo %%I 
    ) else (
     echo %%I %%J 
    ) 
) 

Использование REG вместо REGEDIT имеет то преимущество, что нет повышенных привилегий администратора, не является необходимым для выполнения этого пакетного кода.

Чтобы понять используемые команды и как они работают, откройте окно командной строки, выполните там следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • call /?
  • echo /?
  • for /?
  • goto /?
  • reg /?
  • reg query /?
  • set /?
  • setlocal /?

Ничего не выводится, если ключ реестра не существует. Сообщение об ошибке для обработки STDERR здесь подавлено путем перенаправления его на 2^>nul на устройство NUL. Подробнее см. Статью Microsoft Using command redirection operators.Оператор перенаправления > должны быть экранированы здесь с характером ^ каретки следует интерпретировать как буквенный символ на разборе FOR командной строки и интерпретируется как оператор перенаправления на исполнение REG командной строки ДЛЯ.

+0

Благодарим вас за подробный ответ, однако я думаю, что это не то, что я хотел, я не смог получить результат, который хотел, но я смог узнать, что вы написали. –