Actualmente estoy tratando de reemplazar un script de PowerShell con un script de cmd, ya que es más adecuado para lo que se intenta hacer.

En Powershell estoy usando este bit de código para devolver una lista de directorios de carpetas personales en la computadora

$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

Esto hace lo que quiero y genera una lista de directorios como esta

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

Sin embargo, cuando ejecuto esta línea para extraer la clave de registro

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

Obtengo una salida con muchos datos innecesarios

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

Estos datos se pasan a otro programa *, por lo que una solución alternativa podría ser utilizar datos dentro de las marcas "", sin embargo, también tiene barras diagonales dobles que hacen que los datos sean difíciles de transmitir.

¿Hay una mejor manera de obtener estos valores dentro de CMD o quizás un parámetro que me he perdido y que solo muestra los directorios?

  • -Lo sentimos por no incluir esto antes, sin embargo, este programa no es un programa CMD, es visual básico
0
J. Hodge 29 dic. 2016 a las 15:43

3 respuestas

La mejor respuesta

Si bien no tengo Office instalado para probar, esto debería hacer el trabajo

@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
        )
    )

Utiliza wmic para recuperar la lista de valores definidos bajo la clave indicada y filtrar la salida para recuperar solo la línea con los nombres de esos valores en la forma sNames = {"v1", "v2", "v3"}.

El { se usa para separar el inicio de la línea de la lista de valores (%%a), y esta lista se repite (%%b) para obtener cada valor. El último elemento en la lista incluye un final } que necesita ser eliminado, esto es manejado por %%c usando las comillas en el valor como delimitadores.

La versión equivalente de vbs podría ser

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
MC ND 30 dic. 2016 a las 17:40

Probablemente necesite usar el comando REG QUERY. En un solo archivo bat, le gustaría:

@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

Obtuve esto de ¿Cómo puedo obtener el valor de una clave de registro desde un script por lotes?

0
Community 23 may. 2017 a las 12:01

Aquí hay un código por lotes para obtener la lista de archivos * .pst (no directorios) que funcionan independientemente del número de archivos * .pst y sus nombres de archivo siempre que los nombres de archivo terminen con {{X0 }}.

@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

* Los archivos .pst son archivos de Outlook Personal Storage que son archivos contenedores para correos electrónicos, contactos, ...

El comando FOR ejecuta la aplicación de consola REG para consultar todos los valores de la clave de registro:

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

El resultado en Windows Vista y versiones posteriores de Windows es para el ejemplo:

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

Se muestra la clave del registro y luego los valores del registro, cada uno sangrado con 4 espacios y con 4 espacios entre el nombre del valor y el tipo de valor y 4 espacios entre el tipo de valor y el valor de los datos.

Pero en Windows XP la salida es para el ejemplo:

! 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

Entonces, hay dos primeras líneas de encabezado antes de la clave de registro. Los valores del registro también están sangrados con 4 espacios. Pero hay 1 o más pestañas en lugar de espacios entre el nombre del valor y el tipo de valor y también hay 1 o más pestañas en lugar de espacios entre el tipo de valor y el valor de los datos.

Nota: no sé si REG_SZ es el tipo de valor de registro correcto. No tengo esta clave de registro en absoluto en mi registro de Windows y, por lo tanto, solo agregué los 3 valores de registro como valores de cadena con las cadenas ficticias.

Entonces, la parte difícil es cómo obtener el nombre del valor del registro que contiene también espacios para obtener solo el nombre de los archivos * .pst independientemente del nombre del archivo.

Esto se hace asignando cada línea de salida con la excepción de la primera línea debido a skip=1 a la variable de entorno RegData y obtener después de esta línea todo después de .pst asignado a la variable de entorno {{X3} }.

Si la línea contiene .pst, en cualquier caso, el valor de DelData no es igual al valor de RegData, se llama a la subrutina OutputFileName para procesar e imprimir el archivo nombre del archivo * .pst.

En la subrutina OutputFileName primero, la cadena a la derecha del nombre del archivo * .pst se elimina de RegData utilizando una sustitución de cadena. El siguiente nombre de archivo * .pst se emite sin los 4 espacios de sangría al principio.

Si el número de espacios de sangría no fuera siempre exactamente 4 espacios, la línea echo !RegData:~4! podría reemplazarse por el siguiente código para trabajar independientemente del número de espacios / pestañas de sangría.

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

El uso de REG en lugar de REGEDIT tiene la ventaja de que no se necesitan privilegios elevados de un administrador para ejecutar este código por lotes.

Para comprender los comandos utilizados y cómo funcionan, abra una ventana de símbolo del sistema, ejecute allí los siguientes comandos y lea con cuidado todas las páginas de ayuda que se muestran para cada comando.

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

No se genera nada si la clave de registro no existe. La salida del mensaje de error para manejar STDERR se suprime aquí al redirigirla con 2^>nul al dispositivo NUL . Consulte el artículo de Microsoft Uso de operadores de redirección de comandos para obtener más información. El operador de redirección > se debe escapar aquí con el carácter de intercalación ^ para que se interprete como carácter literal al analizar la línea de comando FOR y se interprete como operador de redirección en la ejecución de < línea de comando strong> REG por FOR .

0
Mofi 29 dic. 2016 a las 14:36