Eu tenho que executá-lo uma segunda vez (às vezes 3-4 vezes) para realmente imprimir o SID
Seu arquivo de lote não está usando setlocal ou delayedexpansion então só funcionará se %user%
estiver definido no ambiente que está chamando o arquivo de lote.
Devido à falta de setlocal
, as variáveis definidas dentro do arquivo de lote são vazadas no shell de comando de chamada e, em seguida, são utilizáveis na próxima vez em que o arquivo de lote for chamado.
Dentro do arquivo de lote (a primeira vez que é chamado)% user% não é utilizável dentro do arquivo de lote porque é referenciado dentro de um bloco de código ( if
):
When a batch file is executed, the command processor (CMD.exe) will parse complete lines and complete compound commands. Variables are replaced by their values just once, BEFORE the commands of the line are executed.
Se você ativar a expansão atrasada :
Delayed Expansion will cause variables within a batch file to be expanded at execution time rather than at parse time, this option is turned on with the SETLOCAL EnableDelayedExpansion command.
Portanto, a primeira vez que você chamar o arquivo em lote %user%
é indefinido no momento da execução e o comando WMIC
falhará com o erro que você anotou na pergunta.
A segunda vez que você chamar o arquivo de lote %user%
é definido (com o valor da execução anterior e seu arquivo de lote aparece para funcionar.
Observe que, se você digitar um nome de usuário diferente na segunda vez que seu arquivo em lote retornará o SID errado (ele usará o nome de usuário inserido na primeira vez em que foi chamado).
Você precisa fazer as seguintes alterações:
-
Adicione
setlocal enabledelayedexpansion
no início do arquivo de lote. -
Substitua
%util%
por!util!
Arquivo em lote modificado:
@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
Exemplo de uso:
> test
DavidPostill
ntp
Administrator
Type the usernameDavidPostill
DavidPostill
%_sid%=S-1-5-21-1699878757-1063190524-3119395976-1000
Leitura Adicional
- Um índice A-Z da linha de comando do Windows CMD
- Uma lista categorizada de comandos do Windows CMD
- enabledelayedexpansion - Expansão com atraso fará com que as variáveis sejam expandidas em tempo de execução e não no tempo de análise.
- setlocal - Defina opções para controlar a visibilidade de variáveis de ambiente em um arquivo em lotes.