Я должен выполнить это второй раз (иногда 3-4 раза), чтобы фактически напечатать SID
Ваш пакетный файл не использует setlocal или delayedexpansion, поэтому он будет работать, только если %user%
он определен в среде, которая вызывает пакетный файл.
Из-за отсутствия setlocal
переменных, установленных внутри командного файла, они просачиваются в командную оболочку вызывающего и могут быть использованы при следующем вызове командного файла.
Внутри пакетного файла (при первом вызове)% user% не может использоваться внутри пакетного файла, поскольку на него ссылаются внутри блока кода ( if
):
Когда выполняется пакетный файл, командный процессор (CMD.exe) будет анализировать полные строки и полные составные команды . Переменные заменяются своими значениями только один раз, ДО выполнения команд строки.
Если вы включите задержку расширения :
Задержка расширения приведет к тому, что переменные в пакетном файле будут расширяться во время выполнения, а не во время анализа, эта опция включается командой SETLOCAL EnableDelayedExpansion.
Таким образом, первый раз, когда вы вызываете пакетный файл, %user%
во время выполнения не определено, и WMIC
команда завершается неудачно с ошибкой, отмеченной вами в вопросе.
Второй раз, когда вы вызываете пакетный файл %user%
, определяется (со значением из предыдущего выполнения и ваш пакетный файл, кажется, работает.
Обратите внимание, что если вы введете другое имя пользователя во второй раз, ваш пакетный файл вернет неправильный SID (он будет использовать имя пользователя, введенное при первом вызове).
Вам необходимо внести следующие изменения:
Добавить
setlocal enabledelayedexpansion
в начале командного файла.Заменить
%util%
на!util!
Модифицированный пакетный файл:
@echo off setlocal enabledelayedexpansion if %errorLevel% == 0 ( SET Users="dir C:\Users\ /B" for /F "tokens=2,*" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /v ProfileImagePath /s ^| find "REG_EXPAND_SZ" ^| findstr /v /i "\\windows\\ \\system32\\"') do ( echo %%~nb echo. ) echo. SET /p "util=Type the username" echo !util! for /f "delims= " %%a in ('"wmic path win32_useraccount where name='!util!' get sid"') do ( if not "%%a"=="SID" ( set _sid=%%a goto :loop_end ) ) ) else ( for /f "delims= " %%a in ('"wmic path win32_useraccount where name='%USERNAME%' get sid"') do ( if not "%%a"=="SID" ( set _sid=%%a goto :loop_end ) ) ) :loop_end echo %%_sid%%=%_sid% endlocal
Пример использования:
> test DavidPostill ntp Administrator Type the usernameDavidPostill DavidPostill %_sid%=S-1-5-21-1699878757-1063190524-3119395976-1000
Дальнейшее чтение
- Индекс AZ командной строки Windows CMD
- Категоризованный список команд Windows CMD
- enabledelayedexpansion - отложенное расширение приведет к тому, что переменные будут расширяться во время выполнения, а не во время анализа.
- setlocal - устанавливает параметры для контроля видимости переменных среды в командном файле.