Search code examples
shellcommandkeyregistrycycle

Need to enumerate unkown registry keys using batch / Win command line


I have a task to enumerate all registry keys in

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render

(subkey names are unknown as they are variable on every PC) and to check specific value for each of them, e.g.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Reder\{45be4e8b-f46c-4c2d-a1ff-ccae63ad5f80}
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Reder\{8997a378-f558-4435-8134-b37565604f54}
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Reder\{a7472931-1ee7-4561-9df3-6efacd010613}

and to check Properties subkey value {a45c254e-df1c-4efd-8020-67d146a850e0},2 in each of them.

In case it is equal to some text, I'll need to change value DeviceState in the parent key.

What I did is usual and worked for me lots of times - I used for /f:

@echo off
Setlocal EnableDelayedExpansion
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render" > c:\temp\reg.txt
for /f %%a in ('find /c /v "" ^< "c:\temp\reg.txt"') do set count=%%a
echo Number of lines: %count%
for /l %%i in (2,1,%count%) do (
echo Current line is: %%i
for /f "usebackq tokens=2 delims=]" %%b in ('find /n /v "" ^< "c:\temp\reg.txt" ^| findstr "^\[%%i\]"') do set test=%%b
echo %test%

set regstring=%test%^\Properties
echo %regstring%
pause
for /f "tokens=3*" %%c in ('reg query %regstring% ^/v "{a45c254e-df1c-4efd-8020-67d146a850e0},2"') do set value=%%c %%d
echo %value%
)

What is strange that line

for /f "usebackq tokens=2 delims=]" %%b in ('find /n /v "" ^< "c:\temp\reg.txt" ^| findstr "^\[%%i\]"') do set test=%%b

doesn't assign a value to "test" variable. At the same time if I put

for /f "usebackq tokens=2 delims=]" %%b in ('find /n /v "" ^< "c:\temp\reg.txt" ^| findstr "^\[%%i\]"') do echo %%b

it outputs %%b to the screen.

I'm lost completely trying to understand why it doesn't pass a value to a variable.

I tried a simpler code without exporting to txt file and later reading from it, but it works neither. It echoes %%a to the screen but doesn't assign a value to "key" variable:

@echo off
Setlocal EnableDelayedExpansion
for /f "usebackq delims=" %%a in (`reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"`)  do (
echo %%a
pause
set key=%%a
echo %key%
for /f "tokens=3*" %%c in ('reg query %key% ^/v "{a45c254e-df1c-4efd-8020-67d146a850e0},2"') do set value=%%c %%d
echo %value% 
)

Could you please advise?


Solution

  • OK, I got it working by myself, may be someone will find it useful. It enumerates subkeys and checks the values in each. After each it compares the value to the known one for Dell and outputs the information.

    in cmd:

    @echo off
    Setlocal EnableDelayedExpansion
    for /f "usebackq delims=" %%a in (`reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"`)  do (
    set key=%%a^\Properties
    echo !key!
    for /f "tokens=3*" %%c in ('reg query !key! ^/v "{a45c254e-df1c-4efd-8020-67d146a850e0},2"') do set value=%%c %%d
    echo !value!
    )
    pause
    

    In powershell:

    $alldevices = Get-ChildItem -Path hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render | select -ExpandProperty name
    foreach($device in $alldevices)
    {
        $dkey = $device -split 'HKEY_LOCAL_MACHINE',2 | select -last 1
        $devitem = "HKLM:"+$dkey+"\Properties"
        $i = Get-ItemProperty $devitem -Name "{a45c254e-df1c-4efd-8020-67d146a850e0},2" | select -ExpandProperty "{a45c254e-df1c-4efd-8020-67d146a850e0},2"
        if ($i -like '*DELL U*') {
            "Dell Displays found:"
            $i
            #The below throws access denied errors
            #$editkey = "HKLM:"+$dkey
            #Set-ItemProperty -Path $editkey -Name DeviceState -Value 268435457
            #Alternative
            $tmpFileFullPath = [System.io.Path]::getTempFileName()
            "Windows Registry Editor Version 5.00" | Out-File -FilePath  $tmpFileFullPath -Append
            " " | Out-File -FilePath  $tmpFileFullPath -Append
            "[$device]" | Out-File -FilePath  $tmpFileFullPath -Append
            #10000001 disables but makes it visible in GUI | 00000004 disables and prevents it from being visible in Recording Devices GUI
            "`"DeviceState`"=dword:10000001" | Out-File -FilePath  $tmpFileFullPath -Append
            " " | Out-File -FilePath  $tmpFileFullPath -Append
            regedit.exe /S $tmpFileFullPath
            $i+" disabled"
        }
    }