Home > Software engineering >  Find first subkey that has specific value
Find first subkey that has specific value

Time:01-12

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

CodePudding user response:

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 (
echo %%%% a=%%a %%%% b=%%b
    for /f "tokens=2*" %%B in ('reg query "%%b" /v "%value_name%" 2^>nul') do (
echo %%%% B=%%B %%%% C=%%C
        set "subkey=%%b"
        goto :break
    )
)

Note that the metavariables a, b, B and C is one of the few instances in batch where case is significant. %%b and %%B are different variable.

See for /? from the prompt for documentation.

for /f "tokens=2,*delims={}" %%u... will parse the text line in question, assign the second "token" to %%u and the rest-of-the-line-after-token-2 (*) to %%v.

Tokens are calculated left-to-right from the format {delimiters}token1{delimiters}token2{delimiters}token3{delimiters}token4... - leading delimiters optional, and {delimiters} is any string of any delimiter specified between delims= and ".

CodePudding user response:

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
  • Related