PhyrePhoX Posted March 7, 2007 Share Posted March 7, 2007 Hello folks, atm i am writing a script to help administrating pc in my office. though i found out a lot of stuff myself, there still is one function i dont know how to turn into code: Finding out who (domain\account) is currently logged in on a remote machine. Sometimes we need this feature to find out who is using a machine without physically going there and taking a look. i HAVE a way of finding out, but it is VERY ugly & slow. Right now i doscall "tasklist /v /s Computername /u Computername/Adminaccount /p PASSWORD" The output takes a while to produce, i then look for the "explorer.exe" task and parse it's user - thats the username of the currently logged in user. there has GOT to be a better and quicker way? normally i manage to find a lot of stuff on google, but seems all the search strings & combinations i used led me to "wrong forum topics" and stuff. hope my question comes across the right way. regards, PhoX Link to comment Share on other sites More sharing options...
giltree Posted March 7, 2007 Share Posted March 7, 2007 How about trying Sysinternals PsLoggedOn and parsing the output? Just a thought.... Link to comment Share on other sites More sharing options...
darkleton Posted March 7, 2007 Share Posted March 7, 2007 (edited) i know its not exactly ideal and there is probably a way using proper script, but microsoft have taken ownership of pstools. one of the tools is psloggedon.exe which can show what you need. so something like: RunWait(@ComSpec & " /c " & "psloggedon" & "\\" & $pcname, "", @SW_HIDE) not sure if its the correct syntax but the exe should be able to give you the correct syntax. **edit** what giltree said Edited March 7, 2007 by darkleton Link to comment Share on other sites More sharing options...
ptrex Posted March 7, 2007 Share Posted March 7, 2007 @PhyrePhoX / darkleton Why don't you stay native and avoid using external tools. Const $HKEY_LOCAL_MACHINE = 0x80000002 Dim $strKeyPath, $strValueName, $strValue $strComputer = "10.0.0.3" $objRegistry=ObjGet("winmgmts:\\" & $strComputer & "\root\default:StdRegProv") $strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon" $strValueName = "DefaultUserName" $objRegistry.GetStringValue ($HKEY_LOCAL_MACHINE, $strKeyPath, $strValueName, $strValue) Consolewrite ($strValue &@CR) $strValueName = "DefaultDomainName" $objRegistry.GetStringValue ($HKEY_LOCAL_MACHINE, $strKeyPath, $strValueName, $strValue) Consolewrite ($strValue &@CR) Enjoy !! ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
darkleton Posted March 7, 2007 Share Posted March 7, 2007 as i said there's probably a scripting way. but i've only been looking at autoit for about 5 days now, so don't know all of its capabilities yet. i'll bear it in mind though, thanks Link to comment Share on other sites More sharing options...
SadBunny Posted March 7, 2007 Share Posted March 7, 2007 my 2ct.: doesn't seem like there's a predefined way in AutoIt to ask for logged-on user on a remote machine, but there is a macro for finding out who is logged on locally. This is @UserName.If you put some effort into this, you might want to do what I did for a very application-specific system that I have on my network and saves me a whole lot of time (so my exact tool is no use to you but it was nice practise in scripting TCP comm and network-related scripting): create a monitoring system with a server-side version and workstation-side version, where the ws-side acts as a TCP-server on a specific port, and the server-side connects to all workstations in a certain IP-range on that port when you run it, and reads out certain information that is presented by the workstation-version. For instance the @UserName as read by the ws-side.(You can ofcourse give as much information as you want from the ws-side to the server-side. I myself use it to report the file dates of certain security patches and AV-updates from the ws-version to the server-version, and the server version compares them to it's own file dates, and if they differ I get a nice popup in my server console.)The nice thing about this system is that you don't need to do anything difficult to access remote registries, you don't even need to be logged on as admin on the server, you can exchange a lot of information, make your own alert system (my little network script here for instance also alarms me when the ws-side has less than 500MB harddisk space), suggest actions based on certain information, etc.. There are some tools freely available that let you monitor this kind of thing, but none of them catered my exact needs and coding this was only a few hours of work.Be sure to make sure any firewall allows the incoming port connection on the workstations though :-) (I troubleshooted my script for HOURS back then before I found out that I forgot to make a domain policy for the Windows XP sp2 Firewall to open my port-of-choice everywhere! Did learn a whole lot about TCP though! heheh)P.S. Sorry for the long post; hope you didn't fall asleep reading it Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
PhyrePhoX Posted March 7, 2007 Author Share Posted March 7, 2007 (edited) Wow people, you're fast! Posted this before lunch and now i already got several working solutions, thanks a bunch! @PhyrePhoX / darkleton Why don't you stay native and avoid using external tools. Yes, i want to avoid using external tools, external as in "not preinstalled in XP". but your approach is much better, thanks, already tested it (although it throws an error when there is a local user logged in on the remote pc - the registry values are not filled then - there must be preinstalled tool that covers that too?). Since you guys solved my problem so easily, you maybe also have some ideas regarding another problem: In order to resolve the account into a full name (surname and given name) and department, a colleague of mine wrote a vb script which i also could not convert into actual autoit code. instead i take the vbscript code, alter it (the variables), write it to a file and dosrun the script via cscript and parse the output - everytime i need the builtin function. Set wshnetwork = CreateObject("WScript.Network") DomainName = "DOMAIN" UserName = "USERNAME" Set user = GetObject("WinNT://" & DomainName & "/" & username & ",user") wscript.echo "FullName: " & user.FullName wscript.echo "Description: " & user.Description i know this is extremely dumb, and only adds up to my 400 lines of spaghetti code - but it works. there's gotta be some other way though, aint it? thanks in advance, PhoX Edited March 7, 2007 by PhyrePhoX Link to comment Share on other sites More sharing options...
PhyrePhoX Posted March 7, 2007 Author Share Posted March 7, 2007 hm, can't edit my post anymore. ptrex, seems your script only is of use in case it is run by a domainadmin (or an account which is admin on both the local and the remote machine). since in our environment the admin accounts are local only i need a way of telling your script to run as another user, including password etc. do you think this is possible? Link to comment Share on other sites More sharing options...
darkleton Posted March 7, 2007 Share Posted March 7, 2007 i don't think this is 100% correct, but it might be a bit closer than having to use VB script : $wshnetwork = ObjCreate("WScript.Network") $DomainName = "DOMAIN" $UserName = "USERNAME" $user = ObjGet("WinNT://" & $DomainName & "/" & $UserName & ",user") _WriteLog ("FullName: " & $user.FullName) _WriteLog ("Description: " & $user.Description) Something like that? Link to comment Share on other sites More sharing options...
PhyrePhoX Posted March 7, 2007 Author Share Posted March 7, 2007 i don't think this is 100% correct, but it might be a bit closer than having to use VB script : ... Something like that? exactly like that. muchas gracias! Link to comment Share on other sites More sharing options...
darkleton Posted March 7, 2007 Share Posted March 7, 2007 have a look for the VB to AU3 converter script somewhere on the forum. It's helped me out a lot. Even if it doesn't convert it 100% correct it gives you an idea of how it should be laid out. A definite must if you are used to using VB a lot Link to comment Share on other sites More sharing options...
saldous Posted March 7, 2007 Share Posted March 7, 2007 Can't you use the DOS commands of %username% and %userdomain% in the script to get this? Link to comment Share on other sites More sharing options...
PhyrePhoX Posted March 7, 2007 Author Share Posted March 7, 2007 have a look for the VB to AU3 converter script somewhere on the forum. It's helped me out a lot.Even if it doesn't convert it 100% correct it gives you an idea of how it should be laid out. A definite must if you are used to using VB a lotoh, i didnt know something like this exists, thanks.Can't you use the DOS commands of %username% and %userdomain% in the script to get this?well, these commands only return the local user, not the one logged in on the remote machine (if i understood this correctly) Link to comment Share on other sites More sharing options...
saldous Posted March 7, 2007 Share Posted March 7, 2007 If you run the script on the remote machine it should give you their details. Something like this: runwait("cmd /c echo %username% > c:\user.txt", "", @SW_HIDE) runwait("cmd /c echo %userdomain% > c:\domain.txt", "", @SW_HIDE) $userfile = "c:\user.txt" $domainfile = "c:\domain.txt" $openuser = FileOpen($userfile,0) $opendomain = FileOpen($domainfile,0) $userline = FileRead($openuser) $domainline = FileRead($opendomain) MsgBox (0, "Logged in user details", "Domain = " & $domainline & " Username = " & $userline) Link to comment Share on other sites More sharing options...
PhyrePhoX Posted March 7, 2007 Author Share Posted March 7, 2007 well, that could be a solution, if there was an easy way of actually running these commands on remote machines. therein lies the whole problem. Link to comment Share on other sites More sharing options...
PhyrePhoX Posted March 8, 2007 Author Share Posted March 8, 2007 (edited) hm, can't edit my post anymore. ptrex, seems your script only is of use in case it is run by a domainadmin (or an account which is admin on both the local and the remote machine). since in our environment the admin accounts are local only i need a way of telling your script to run as another user, including password etc. do you think this is possible? found a way to run the script - i just have to mount the administrative share of the remote computer in order to have the right to execute the "get values from registry" program. so the only problem remaining is to find out if (&who) a local user is logged on. $strComputer = "Machine" $adminpw = "Password" DriveMapAdd("", "\\" & $strComputer & "\c$", 0, $text & "\administrator" & $adminpw) Const $HKEY_LOCAL_MACHINE = 0x80000002 Dim $strKeyPath, $strValueName, $strValue $objRegistry=ObjGet("winmgmts:\\" & $strComputer & "\root\default:StdRegProv") $strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon" $strValueName = "DefaultUserName" $objRegistry.GetStringValue ($HKEY_LOCAL_MACHINE, $strKeyPath, $strValueName, $strValue) MsgBox(1,"",$strValue &@CR) $strValueName = "DefaultDomainName" $objRegistry.GetStringValue ($HKEY_LOCAL_MACHINE, $strKeyPath, $strValueName, $strValue) MsgBox(1,"",$strValue &@CR) hm, i managed to write autotit instead of autoit twice in this post, only realized that because i remembered to delete our adminpw and thus searched the code again. hm, seems i'm a freak 2nd Edit: haha, i had my source wrong, it still doesnt work on remote pcs Edited March 8, 2007 by PhyrePhoX Link to comment Share on other sites More sharing options...
VicFontaine Posted March 8, 2007 Share Posted March 8, 2007 (edited) @ PhyrePhoX Func _GetUserName($strClient) Local $objWMIService, $objItem, $colItems, $strUser, $strDomain, $Result $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strClient) $colItems = $objWMIService.InstancesOf("Win32_Process") If IsObj($colItems) Then For $objItem In $colItems If ($objItem.Caption = "explorer.exe") Then $Result = $objItem.GetOwner($strUser, $strDomain) If (Not @error) And ($Result = 0) Then Return $strUser EndIf Next EndIf Return "" EndFunc Enjoy Vic Fontaine Edited March 8, 2007 by VicFontaine Link to comment Share on other sites More sharing options...
PhyrePhoX Posted March 9, 2007 Author Share Posted March 9, 2007 @ PhyrePhoX Func _GetUserName($strClient) Local $objWMIService, $objItem, $colItems, $strUser, $strDomain, $Result $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strClient) $colItems = $objWMIService.InstancesOf("Win32_Process") If IsObj($colItems) Then For $objItem In $colItems If ($objItem.Caption = "explorer.exe") Then $Result = $objItem.GetOwner($strUser, $strDomain) If (Not @error) And ($Result = 0) Then Return $strUser EndIf Next EndIf Return "" EndFunc Enjoy Vic Fontainethanks for the reply, but how do i "impersonate" another account? the situation is as follows: on my workstation i am logged in as a regular domain user with no special privileges. in order to read out the process list of the "target pc" i have to use the (on the target pc) local administrator account. how do i set these credentials? many thanks in advance! Link to comment Share on other sites More sharing options...
PhyrePhoX Posted March 9, 2007 Author Share Posted March 9, 2007 (edited) expandcollapse popup;- This function returns the user who is logged in on a remote machine, provided you know the proper admin credentials of the remote machine. ; This assumes you either have ONE domain or local accounts (can be changed easily). ; In our environment we (the admins) only have LOCAL adminrights, our useraccounts are no domainadminaccounts. ; you can rewrite this script so that you can use domainadminaccounts whatever. ; one problem remains: execution of the script does take a while (as in a few seconds). tested on win2k and winxp (both local and remote) ; no extratools needed, tasklist is already preinstalled in windows ; p.s: i know this code is ugly as hell, but it works ;) #include <String.au3> Func _GetUserName($hostname,$admaccount,$adminpw,$domain) Local $process = Run("tasklist /v /fo list /fi ""IMAGENAME eq explorer.exe"" " & "/s "& $hostname & " /u " & $hostname & "\" & $admaccount & " /p " & $adminpw, "", @SW_HIDE, 2) Local $_buffer = '' Local $Result Local $exploreruser Do $_buffer &= StdoutRead($process) Until @error If StringReplace($_buffer, 'explorer.exe', '') <> $_buffer Then If StringReplace($_buffer, $domain & '\', '') <> $_buffer Then ;Show Domainuser $exploreruser = _StringBetween($_buffer,$domain & "\",@CRLF) Return $exploreruser[0]& " (Domain account!)" Else ;No domainuser, show local logged in account $exploreruser = _StringBetween($_buffer,$hostname&"\",@CRLF) Return $exploreruser[0] & " (Local account!)" EndIf Else Return "no user logged in locally (or no windows OS :D)" EndIf EndFunc ;Example usage ;~ $hostname = "machine1" ;~ $admaccount = "administrator" ;~ $adminpw = "foo" ;~ $domain = "domain" ;~ MsgBox(1,"Currently logged in user on " & $hostname & " is:",_GetUserName($hostname,$admaccount,$adminpw,$domain)) though it is ugly and i still have to parse cmd, it suits my needs. this script is working, take it Edited March 9, 2007 by PhyrePhoX Link to comment Share on other sites More sharing options...
gcue Posted January 9, 2009 Share Posted January 9, 2009 this is more a function that shows the primary user of a machine not whose logged on... bc if no one is logged on it still reports the same name... @PhyrePhoX / darkleton Why don't you stay native and avoid using external tools. Const $HKEY_LOCAL_MACHINE = 0x80000002 Dim $strKeyPath, $strValueName, $strValue $strComputer = "10.0.0.3" $objRegistry=ObjGet("winmgmts:\\" & $strComputer & "\root\default:StdRegProv") $strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon" $strValueName = "DefaultUserName" $objRegistry.GetStringValue ($HKEY_LOCAL_MACHINE, $strKeyPath, $strValueName, $strValue) Consolewrite ($strValue &@CR) $strValueName = "DefaultDomainName" $objRegistry.GetStringValue ($HKEY_LOCAL_MACHINE, $strKeyPath, $strValueName, $strValue) Consolewrite ($strValue &@CR) Enjoy !! ptrex Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now