Search code examples
batch-fileregistry

Find first subkey that has specific value


I am struggling to finish up this batch file and I am not sure what I am missing, although I am certain it's a small mistake. I think it's with my delims or possibly the subkey naming convention.

@echo off
@echo 12 (2014)
@echo 13 (2016)
@echo 14 (2017)
@echo 15 (2019)

set /p "version=Enter Version: "
set "value_name=ParentInstance"
set "value_data=MSSQL%version%E.LOCALDB"
set "key_path=HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SQL Server\UserInstances"

for /f "tokens=2* delims={}" %%a in ('reg query "%key_path%" /s 2^>nul') do (
    for /f "tokens=2*" %%b in ('reg query "%%b" /v "%value_name%" 2^>nul') do (
        set "subkey=%%b"
        goto :break
    )
)
:break
if defined subkey (
    reg add "%subkey%" /v "%value_name%" /t REG_SZ /d "%value_data%" /f
    echo Updated Value data of key : %subkey% to : %value_data%
) else (
    echo Subkey with value name "%value_name%" not found.
)
endlocal
TIMEOUT /t 5 /nobreak

I am looking for a way to retrieve all subkeys under

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SQL Server\UserInstances

Then for each subkey check if it has a value named "ParentInstance" by querying the value under that subkey. If it finds any, it stores that subkey in the variable "subkey", then uses the reg add command to change the data of the value named "ParentInstance" to the value in the variable "value_data" which is "MSSQL%version%E.LOCALDB" (%version% is a number that gets input).

Example of Registry (UserInstances may include multiple subkeys)

enter image description here


Solution

  • To perform the task using the same methodology you laid out in your question:

    • Get all next level subkeys within your %key_path%, (I added some additional robustness targeting only those child keys with the format {*-*-*-*-*}).
    • For each of those subkeys, query if it has a value named %value_name%.
    • If it finds any, change the value data for %value_name% for that subkey using the reg add command to the content of the variable, %value_data%.
    For /F "Delims=" %%G In ('%SystemRoot%\System32\reg.exe Query "%key_path%" /F "{*-*-*-*-*}" 2^>NUL ^| %SystemRoot%\System32\find.exe "\"') Do %SystemRoot%\System32\reg.exe Query "%%G" /F "%value_name%" /V /E 2>NUL 1>&2 && %SystemRoot%\System32\reg.exe Add "%%G" /V "%value_name%" /D "%value_data%" /F 1>NUL