Hardoman
Hardoman

Reputation: 292

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?

Upvotes: 2

Views: 1557

Answers (2)

Xxx xxx
Xxx xxx

Reputation: 11

In powershell is better to use itself directly than creating .reg file for regedit.exe

Example:

$dkey = "HKLM:"+$dkey
Set-ItemProperty -Path $dkey -Name DeviceState -Value 00000004
Set-ItemProperty -Path $devitem -Name '{b3f8fa53-0004-438e-9003-51a46e139bfc},3' -Value 0

And if somebody wants to use these registry changes as GPO startup script then first additional GPO must be created to give SYSTEM user elevated rights to change these registry keys:

  1. Open according GPO or create a new GPO.
  2. Navigate to the following location: [Computer Configuration\Policies\Windows Settings\Security Settings\Registry]
  3. Right-click right-panel, choose Add Key to add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio" and give Full Control permission to Admin and SYSTEM.

But thank you very much for script above. I adjusted it for project of removing all VMware audio devices and uncheck "Allow applications to take exclusive control of this device" option in Teradici audio drivers on my Clearcube Zeroclients to avoid sound control conflicts between voice communicators like Skype.

Upvotes: 1

Hardoman
Hardoman

Reputation: 292

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"
    }
}

Upvotes: 1

Related Questions