WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

User Profiles

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Get Logged In User from Local System Account


Question:

I am working on a Winbatch script which is rolled out via Novadigm Radia. The script is controlling a major upgrade and emails the help desk with details if certain events happen. I want it to mail the users name but because Radia runs in the system context I am having a problem getting the logged on users name. I am also experiencing problems finding out if user is logged on or not. ( Radia will install applications even if the user is logged off ).
Radia shows the USERPROFILE variable as d:\profiles\LocalService
USERNAME is not reported. 
SESSIONNAME is not reported.
Any ideas on how to achieve this ?

Answer:

See Also: http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/How~To/User~Profiles+Best~way~to~find~the~currently~logged~in~user.txt

You might be able to obtain the logged in user from the registry. However, all methods that rely on the registry are unreliable in various situations. It is possible for a user's profile to be held open such that their registry hive is still in memory when they've logged out.

; CurrentInteractiveUser(@True) = Get user and domain
; CurrentInteractiveUser(@False) = Get user only

#DefineFunction CurrentInteractiveUser(IncludeDomain)
User = ""
Domain = ""
Key = RegOpenKey(@REGUSERS,"")
SIDList = RegQueryKeys(Key)
RegCloseKey(Key)
For i = 1 To ItemCount(SIDList,@TAB)
   SID = ItemExtract(i,SIDList,@TAB)
   If RegExistKey(@REGUSERS,StrCat(SID,"_Classes"))
      Key = "%SID%\Software\Microsoft\Windows\CurrentVersion\Explorer[Logon User Name]"
      If RegExistValue(@REGUSERS,Key) Then User = RegQueryValue(@REGUSERS,Key)
   EndIf
Next
If IncludeDomain && User<>""
   Domain = RegQueryValue(@REGMACHINE,"Software\Microsoft\Windows NT\CurrentVersion\Winlogon[DefaultDomainName]")
   User = StrCat(Domain,"\",User)
EndIf
Return(User)
#EndFunction

; Let"s try it
User = CurrentInteractiveUser(@FALSE)
DomainUser = CurrentInteractiveUser(@TRUE)
Message(User,DomainUser)

If I remember correctly, WMI has functionality that can retrieve the desired information reliably.

objLocator = ObjectCreate("WbemScripting.SWbemLocator")
errormode(@off)
objService = objLocator.ConnectServer(Computername,"root/cimv2","","") 
errormode(@cancel)
objSecurity = objService.Security_ 
objSecurity.ImpersonationLevel = 3

class = "Win32_ComputerSystem"
; query instances
query = "SELECT * FROM Win32_ComputerSystem"
colInstances = objService.ExecQuery(query)
; loop once for each instance
foreach objInstance in colinstances
	type = ObjectTypeGet(objInstance)
	if type=="EMPTY" then break
	; obtain properties
	username = objinstance.UserName
next

objSecurity = 0
objService = 0
objLocator = 0

You can also use the Terminal Server extender to enumerate the connected sessions on a desktop system running WinXP & newer, too. Each session may then be queried to see what user is logged on to the session and whether the session is connected to the physical console on the workstation. If the workstations are Win2K or older, then this method won't work.

Call wtsGetActiveConsoleSessId() first in order to find out what session id # is associated with the console.The actual session id # will vary in some cases, especially if WinXP has F.U.S. [Fast User Switching] enabled. You'll also see the session id # varying on Win2K3 servers when you connect to the console in remote admin mode as opposed to just having remote admin session that wasn't started with the switch that tells it to connect to the console.

On workstation operating systems, there's only one connected session allowed, so if there's multiple simultaneous users logged on in different sessions, all but one of those sessions will be in a disconnected state and the remaining one will be connected.

Alternatively, you can call wtsEnumSessions() to get back an array of session id #s, and then you can iterate thru the array in a loop to process session that currently exists. This would be by far the most reliable method that would work on all variants & versions of Windows that have terminal services built into them in one form or another.

Then, when you do call wtsQuerySessionInfo() for that particular session id #, you can be certain that you've the right session id # to be querying for information. If there's no user logged on to that session, then the array element [14] should be an empty string.

ServerSpec = ''
SessId = wtsGetActiveConsoleSessId()
arrSession = wtsQuerySessionInfo( ServerSpec, SessId )
strLoggedOnUser = arrSession[14]
if strLoggedOnUser == ""
   Message( 'Logged in user for SessionID #':SessId, 'No user logged on' )
else
   Message( 'Logged in user for SessionID #':SessId, strLoggedOnUser )
endif

Article ID:   W17034
File Created: 2014:07:18:09:51:38
Last Updated: 2014:07:18:09:51:38