I have to execute it a second time (sometimes 3-4 times) to actually print the SID
Your batch file is not using setlocal or delayedexpansion so it will only work if %user%
is defined in the environment that is calling the batch file.
Because of the lack of setlocal
variables set inside the batch file are leaked into the calling command shell and they are then usable the next time the batch file is called.
Inside the batch file (the first time it is called) %user% is not usable inside the batch file because it is referenced inside a code block (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.
If you enable delayedexpansion:
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.
So the first time you call the batch file %user%
is undefined at execution time and the WMIC
command fails with the error you noted in the question.
The second time you call the batch file %user%
is defined (with the value from the previous execution and your batch file appears to work.
Note that if you enter a different user name the second time your batch file will return the wrong SID (it will use the user name entered the first time it was called).
You need to make the following changes:
Add setlocal enabledelayedexpansion
at the beginning of the batch file.
Replace %util%
with !util!
Modified batch file:
@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
Example Usage:
> test
DavidPostill
ntp
Administrator
Type the usernameDavidPostill
DavidPostill
%_sid%=S-1-5-21-1699878757-1063190524-3119395976-1000
Further Reading