Как получить значение реестра и установить его в переменную в пакетном файле

Вопрос или проблема

Мне нужно получить значение из ключа реестра и сохранить его в переменной, используя пакетный файл.

Я написал базовую команду, чтобы проиллюстрировать свою логику (используя echo вместо установки переменной):

for /f "tokens=3 delims=    " %%a in ('reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername" ^|findstr /ri "REG_SZ"') do echo=%%a

Я ожидаю, что имя пользователя будет выведено на экран, но этого не происходит.

Я уверен, что значение реестра “LastUsedUsername” не пустое, в нем действительно есть данные.
Кроме того, разделитель — это табуляция, а не пробелы.

РЕДАКТИРОВАТЬ

Если я просто набираю

reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername"

… это возвращает:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
    LastUsedUsername    REG_SZ    Администратор

Этот код

reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername" ^| findstr /ri "REG_SZ"

… возвращает:

    LastUsedUsername    REG_SZ    Администратор

Затем, когда я использую команду for, я просто не получаю вывода от echo.

Вам не нужен переключатель delims вообще, поскольку по умолчанию используется пробел, который и возвращает reg query. Создавая bat-файл с этим циклом for и реестром на ключе, с которым я работаю, я получаю правильный echo, в моем случае значение “Red” цвета фона RGB равно 55:

for /f "tokens=3" %%a in ('reg query "HKCU\Control Panel\Colors"  /V Background  ^|findstr /ri "REG_SZ"') do echo %%a

Одобренный ответ не верен в некоторых ситуациях – если значение, прочитанное из реестра, содержит пробелы (Program Files (x86)), то возвращается только первая часть значения (‘Program’).
То, что я разработал, это:

FOR /F "tokens=2* skip=2" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion" /v "CommonFilesDir"') do echo %%b

Результат C:\Program Files\Common Files

Синтаксис команды DOS верен. Я бы поставил под сомнение наличие у вас правильного значения ключа реестра. Просто введите часть req query… в командной строке и посмотрите, что она возвращает. Я использую Win 7, и я не нахожу ключа, LastUsedUsername, определенного в HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon

setx может сделать то, что вам нужно, без необходимости в скрипте:

setx DefaultUserName /k "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName"

Примечание: Переменную нельзя использовать в текущем сценарии команды, так как она задается в окружении пользователя, а не в текущем окружении. Проверьте с помощью

echo %DefaultUserName% (не работает OOTB, но будет работать в новом окне cmd)
reg query "HKCU\Volatile Environment" /v "DefaultUserName" (не работает)
reg query "HKCU\Environment" /v "DefaultUserName" (работает)

Эта короткая процедура назначит тип и значение reg на: getkeytype/ getkeyvalue
и установит errorlevel и errror value, если не найдено, вот три примера использования:

@echo off
setlocal enableextensions enabledelayedexpansion & REM для получения значения var при exec с !varNm!

call :SUBGETKEY HKLM\SOFTWARE\Microsoft\nonExistantKey /v nothing
echo Err:%errorlevel%, Type:!getkeytype!, Value:!getkeyvalue!

call :SUBGETKEY "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "defaultUsername"
echo Err:%errorlevel%, Type:!getkeytype!, Value:!getkeyvalue!

call :SUBGETKEY "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "Shutdownflags"
echo Err:%errorlevel%, Type:!getkeytype!, Value:!getkeyvalue!

pause

goto :FIN

:SUBGETKEY
  set SubKeyParam= %*&  rem получить параметры, добавить пробел, чтобы не было пустоты
  REM запрос GETKEY, возвращает: getkeytype, getkeyvalue
  rem если не найдено: errorlevel установлен, и "error" на переменных
  set getkeyaux=error error&  REM значения возвращаемых значений по умолчанию не найдены
  FOR /F "tokens=2* delims=_" %%A IN ('REG.EXE QUERY %SubKeyParam% 2^>nul') DO (
    set getkeyaux=REG_%%A%%B
  )
  rem echo -%errorlevel%-!getkeyaux!-
  for /f "tokens=1*" %%I in ("!getkeyaux!") do (
    set getkeytype=%%I
    set getkeyvalue=%%J
  ) & rem {call} устанавливает ERROLEVEL 1, иначе {call } устанавливает ERROLEVEL 0
     if %getkeytype%==error (CALL) else (CALL )
  goto :FIN

:FIN

Ответ или решение

Для экспертов в области информационных технологий работа с реестром Windows зачастую является обычной практикой. Вопрос о том, как извлечь значение из реестра Windows и сохранить его в переменной с помощью пакетного файла, требует комплексного подхода и детального понимания синтаксиса командной строки Windows. Рассмотрим эту задачу с использованием подхода "ТЕА" (теория, пример, применение), чтобы детально понять, как это можно реализовать.

Теория

Реестр Windows — это иерархическая база данных, используемая ОС для хранения низкоуровневых настроек системы и приложений. Для извлечения данных из реестра обычно используется команда reg query, а для обработки этих данных в пакетных файлах часто применяется цикл for.

Команда reg query позволяет выполнять запросы к определенному ключу реестра и извлекать значения. В своей основе команда возвращает информацию в формате, который включает полное имя ключа, имя значения, тип данных (например, REG_SZ), и само значение.

Цикл for в пакетных файлах может принимать результаты других команд, выполняемых в командной строке, и обрабатывать их. Параметры tokens и delims используются для разбора выходных данных. Tokens указывает, какие элементы строки использовать, а delims определяет разделители.

Пример

Рассмотрим вопрос, как извлечь и сохранить в переменной имя последнего использованного пользователя в Windows с помощью пакетного файла. Известно, что нужное значение содержится по пути HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon с именем LastUsedUsername.

Ваш код изначально выглядел так:

for /f "tokens=3 delims=    " %%a in ('reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername" ^|findstr /ri "REG_SZ"') do echo=%%a

Эта команда должна была вывести значение "LastUsedUsername", но, по словам автора, она не выдавала ожидаемого результата. Причина в неверно указанных разделителях и потенциальных проблемах с разбором строки.

Применение

Теперь исправим код, чтобы он правильно обрабатывал вывод команды reg query:

@echo off
setlocal

for /f "tokens=3*" %%a in ('reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername"') do (
    set LastUsedUsername=%%b
)

echo Last Used Username: %LastUsedUsername%

endlocal

Объяснение

  1. Региональное окружение и переменные: Команда setlocal используется для того, чтобы изменения окружения (такие как установка переменных) были локальными для скрипта.

  2. Использование tokens и delims: Параметр tokens=3* важен, так как он указывает на использование третьего поля и всех остальных, если значение содержит пробелы. Таким образом, если имя пользователя состоит из более чем одного слова, весь остаток строки будет захвачен.

  3. Сохранение и вывод значения: Мы сохраняем извлеченное значение в переменной LastUsedUsername и затем выводим его с помощью команды echo.

С помощью этого подхода можно легко адаптировать скрипт для извлечения других значений из реестра, изменяя путь к ключу и имя значения.

Это метод программирования позволяет автоматизировать задачи администрирования и мониторинга, которые очень ценны в больших корпоративных IT-инфраструктурах, предоставляя быстрый доступ к критически важной информации.

В итоге, такой детальный подход не только решает вашу непосредственную задачу, но и предоставляет гибкий механизм для работы с любыми данными реестра в Windows через пакетные файлы.

Оцените материал
Добавить комментарий

Капча загружается...