Oct 7, 2013

Function: EnumerateLoggedOnSIDs

Bases on GetCurrentUserSID; retrieves SIDs of logged on users by matching their usernames to corresponding HKU registry subkeys. Testing in progress, confirmed working on XP and Windows 7. Code below may not be final.
@echo off
:: works globally; uses vars: sids, opsys, ocparam, skip, var, var0, var1, retv, username_for_sid, appdata_username, userprofile_username
:: contains GTweak procedures: OsCheck (modified); RegQueryValue (modified); IsReadable; IsRunWithElevatedRights, TruncateTrailingSpaces, MakeSemicolonSeparatedVariable (modified)
:: requires reg.exe; find.exe and OS >= Windows 2000
call:EnumerateLoggedOnSIDs securityid
for %%A in (%securityid%) do (for /f "tokens=1,2 delims=+" %%B in ('echo %%A') do (echo %%C = %%B))
pause
exit
:EnumerateLoggedOnSIDs
if not exist "%windir%\system32\reg.exe" (exit/b1)
reg add "HKLM\SOFTWARE\Microsoft\WBEM" /v "" /d "" /f>nul 2>&1||exit/b1
if not exist "%windir%\system32\find.exe" (exit/b1)
set sids=
call:OsCheck
set opsys=%errorlevel%
set ocparam=
for /f "tokens=2* delims=\" %%G in ('reg query HKU') do (call:checkifsid %%G)
set %1=%sids%
for %%A in (opsys sids skip var var1) do set %%A=
exit/b0
:checkifsid
set var0=%*
if not "%var0:~0,1%"=="S" (goto checkifsid_out)
if /i "%var0:~-8%"=="_Classes" (goto checkifsid_out)
for /f "tokens=1-8 delims=-" %%G in ('echo %var0%') do (
 if not "%%G"=="" (
  if not "%%H"=="" (
   if not "%%I"=="" (
    if not "%%J"=="" (
     if not "%%K"=="" (
      if not "%%L"=="" (
       if not "%%M"=="" (
        if not "%%N"=="" (
         call:assignsidtousername
        )
       )
      )
     )
    )
   )
  )
 )
)
:checkifsid_out
set var0=
exit/b0
:RegQueryValue
call:IsReadable %1 %2||exit/b1
for /f "%skip%*" %%G in ('reg query %1 /v %2') do (
 set retv=%%G %%H
)
call:TruncateTrailingSpaces retv
exit/b0
:IsReadable
reg query %1 /v %2>nul 2>&1&&exit/b0
exit/b1
:assignsidtousername
call:RegQueryValue "HKU\%var0%\Volatile Environment" "APPDATA"
set username_for_sid=
if %opsys% GEQ 4 (
 call:CompareUserNameCandidates
) else (
 call:ExtractUserName retv username_for_sid
 set retv=
)
if defined username_for_sid (echo.>nul) else (set username_for_sid=???)
call:MakeSemicolonSeparatedVariable "%username_for_sid%" "%var0%" sids
set username_for_sid=
exit/b0
:CompareUserNameCandidates
set appdata_username=%retv%
call:RegQueryValue "HKU\%var0%\Volatile Environment" "USERPROFILE"
set userprofile_username=%retv%&set retv=
call:ExtractUserName appdata_username appdata_username
call:ExtractUserName userprofile_username userprofile_username
if /i "%appdata_username%"=="%userprofile_username%" (set username_for_sid=%appdata_username%)
set userprofile_username=
set appdata_username=
exit/b0
:ExtractUserName
for /f "tokens=3 delims=\" %%G in ('set %1') do set %2=%%G
exit/b0
:OsCheck
for /f "tokens=3*" %%G in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v "ProductName"^|find "ProductName"') do set ocparam=%%G %%H
echo.%ocparam%|find "Windows 7">nul 2>&1&&set skip= tokens=3&&exit/b6
echo.%ocparam%|find "XP">nul 2>&1&&set skip=skip=4 tokens=3&&exit/b2
echo.%ocparam%|find "Vista">nul 2>&1&&set skip= tokens=3&&exit/b4
echo.%ocparam%|find "2003">nul 2>&1&&set skip= tokens=3&&exit/b3
echo.%ocparam%|find "2000">nul 2>&1&&set skip=skip=4 tokens=3&&exit/b1
echo.%ocparam%|find "2008">nul 2>&1&&set skip= tokens=3&&exit/b5
set skip= tokens=3
exit/b6
:TruncateTrailingSpaces
set var=[%% %1:~-1 %%]
set var=%var: =%
call set var=%var%
if not "%var%"=="[ ]" (set var=&set var1=&exit/b0) else (call:TruncateTrailingSpaces_2 %1&goto TruncateTrailingSpaces)
:TruncateTrailingSpaces_2
set var1=%% %1:~0,-1 %%
set var1=%var1: =%
call set %1=%var1%
exit/b0
:MakeSemicolonSeparatedVariable
set var=%% %3 %%
set var=%var: =%
if defined %3 (call set %3=%var%;%1+%2) else (set %3=%1+%2)
set var=
exit/b0

Update (October the 7th, 2013): I enhanced this script, as I did with GetCurrentUserSID. Tested/working in Windows XP and Windows 7.
@echo off
:: requires reg.exe and OS >= Windows 2000
call:EnumerateLoggedOnSIDs securityid_container
if %errorlevel%==0 (for %%A in (%securityid_container%) do (for /f "tokens=1,2 delims=+" %%B in (%%A) do (echo %%C = %%B)))
if %errorlevel%==1 (echo Required component missing.)
if %errorlevel%==2 (echo Required registry writes could not be performed or insufficient privileges.)
if %errorlevel%==3 (echo Unknown error, SIDs not found?)
pause
exit
:EnumerateLoggedOnSIDs
setlocal
if not exist "%windir%\system32\reg.exe" (set err=1&goto elosids_endproc)
reg add "HKLM\SOFTWARE\Microsoft\WBEM" /v "" /d "" /f>nul 2>&1||set err=2&&goto elosids_endproc
for /f "tokens=2* delims=\" %%G in ('reg query HKU') do (call:checkifsid %%G)
if defined sids (set err=0) else (set err=3)
:elosids_endproc
endlocal&set %1=%sids%&exit/b%err%

:checkifsid
set var0=%*
if "%var0:~0,1%"=="S" (if not "%var0:~-8%"=="_Classes" (for /f "tokens=1-8 delims=-" %%G in ("%var0%") do (if not "%%G"=="" (if not "%%H"=="" (if not "%%I"=="" (if not "%%J"=="" (if not "%%K"=="" (if not "%%L"=="" (if not "%%M"=="" (if not "%%N"=="" (for /f "tokens=3*" %%O in ('reg query "HKU\%var0%\Volatile Environment" /v "APPDATA"') do (if "%%P"=="" (for /f "tokens=3 delims=\" %%Q in ("%%O") do (call:makesidsvar %var0% %%Q)) else (for /f "tokens=3 delims=\" %%Q in ("%%O %%P") do (call:makesidsvar %var0% %%Q))))))))))))))
exit/b0
:makesidsvar
for /f "tokens=1,2*" %%A in ("%*") do (if "%%C"=="" (set sid=%%A&set usrname=%%B) else (set sid=%%A&set usrname=%%B %%C))
if defined sids (set sids=%sids%;"%usrname%+%sid%") else (set sids="%usrname%+%sid%")
exit/b0

No comments:

Post a Comment