Jump to content
Sign in to follow this  
KickStarter15

Get IP addresses and Usernames logged on the network computers

Recommended Posts

KickStarter15

Hi Experts,

Good day!

I would like to ask if this is possible that in my station we have more than 50 PC's in used and I need to get their IP addresses and the username logged on that certain computer?

 

Example:

Computer 1 has IP 123.123.123 and user is jJhonson

Computer 2 has IP 123.123.124 and user is pSamsun

etc.... and so on...

 

Would this be possible? I haven't started any yet and trying to google something but can't compile one. Hope you have any samples that I can start with.

 

Thanks!

KS15


Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare.

Share this post


Link to post
Share on other sites
orbs

@KickStarter15,

you can easily scan the IP range, and for each IP that is a Windows host, use the utility PsLoggedOn.exe to determine the currently logged-on user. you can also - or instead - query the registry for the last-logged-on user, so you can get a result even if no-one is currently logged-on to a given target.

try it on, ask for help once you have something running.

Share this post


Link to post
Share on other sites
Chimp

you could also use the following wmic command in a dos prompt:

wmic /node:hostname computersystem get username /value

change the hostname with your clientname or IP address.

Few days ago I posted an example to show how to use a multitask utility. That example query infos from remote clients, and one of that info is the loggedon username. Now if you have a list of hostnames (or IP addresses) you can use that example by inserting your list.
Or, if you have not a list, you can scan your lan using another my utility I wrote a while ago. After that the scanner returns the found devices, it queryes those devices to get your wanted infos.

here is a simple example that shows how to use both of the above utilityes to quickly scan you lan and then query the found clients (all is done in multitasking)

you have to downlad the 2 udf MultiPing.au3 and MultiTask.au3 and save those along with this script

; #RequireAdmin
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include '.\MultiTask.au3' ; <-- get this from the following link:
; https://www.autoitscript.com/forum/topic/192157-multi-task-easily-run-and-mange-many-processes/
;
#include '.\MultiPing.au3' ; <-- get this from the following link:
; https://www.autoitscript.com/forum/topic/156395-versatile-multi-ping/
;

Global $aScanLan = _nPing() ; LAN Scanner (search for alive devices)
; _ArrayDisplay($aScanLan)
$aIPList = _ArrayExtract($aScanLan, 1, -1, 0, 0) ; extract only the first column of the found devices
; _ArrayDisplay($aIPList)

Global $hGrid ; The ListView Handle
Global $ahGrid[1] ; An array to keep handles of any listview row

Example()
MsgBox(0, "Debug:", "Done" & @CRLF & "Hit OK to exit")

Func Example()
    Local $Form1 = GUICreate("Clients status", 760, 400)
    ;
    ; Create the ListView
    $hGrid = GUICtrlCreateListView("HostName|IP|Info|Last reboot|CPU|Last logon|Current logon", 0, 0, 760, 400)
    _GUICtrlListView_SetColumnWidth($hGrid, 0, 140) ; HostName
    _GUICtrlListView_SetColumnWidth($hGrid, 1, 100) ; IP
    _GUICtrlListView_SetColumnWidth($hGrid, 2, 80) ; Ping info ms or Off or Unknown or Timeout)
    _GUICtrlListView_SetColumnWidth($hGrid, 3, 120) ; Last Reboot
    _GUICtrlListView_SetColumnWidth($hGrid, 4, 40) ; cpu load
    ; last 2 columns a mutually exclusive. If there is a user logged it's shown on the last column
    ; if there is not a user logged then the last user that was logged  is shown on column 4 instead
    _GUICtrlListView_SetColumnWidth($hGrid, 5, 140) ; Last logged UserId (if nobody is logged now)
    _GUICtrlListView_SetColumnWidth($hGrid, 6, 140) ; Currently logged UserId
    _GUICtrlListView_SetExtendedListViewStyle($hGrid, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) ; show grid; select whole row
    ;
    GUISetState(@SW_SHOW)

    ; following line is needed if you have to refill the listview
    ; _GUICtrlListView_DeleteAllItems(GUICtrlGetHandle($hGrid)) ; empty the listview

    ReDim $ahGrid[UBound($aIPList)]

    ; this loop will run all needed tasks at once.
    ; The results of the tasks will be managed by the callback functions (nearly) autonomously and asynchronously
    For $i = 0 To UBound($aIPList) - 1
        $ahGrid[$i] = _GUICtrlListView_AddItem($hGrid, "") ; create a listview row
        ;
        ; ... for each client ...
        ;
        ; spawn ping commands. result will be send to the _PingParse() function
        _TaskRun($i, "Ping -a -n 1 -4 " & $aIPList[$i], "_PingParse")

        ; spawn commands to recall LoggedOn User. Result will be send to the _LoggedOn() function
        _TaskRun($i, "wmic /node:" & $aIPList[$i] & " computersystem get username /value", "_LoggedOn", 5) ; 5 = timeout in 5 seconds

        ; spawn commands to recall Last reboot time. result will be send to the _LastReboot() function
        _TaskRun($i, "wmic /node:" & $aIPList[$i] & " os get lastbootuptime /value", "_LastReboot", 5)

        ; spawn commands to recall % of CPU load. result will be send to the _CPU_load() function
        _TaskRun($i, "wmic /node:" & $aIPList[$i] & " cpu get loadpercentage /value", "_CPU_load", 7)
    Next

    ; now, while all tasks are running
    ; we could perform other activities in the meantime
    ; or we can wait the end of all the tasks
    Do
        Sleep(250)
        ; you could perform other jobs here while waiting for the tasks to finish
    Until Not _TasksCheckStatus() ; <-- this function performs management of running tasks
    ;                                   and should be called as often as possible

EndFunc   ;==>Example

; below are CallBack functions

; #FUNCTION# ====================================================================================================================
; Name ..........: _PingParse (a callback function)
; Description ...: this function analize the output of a ping command and "extract" needed infos
;                  it fills columns 0 1 and 2 of the list view ($aTarget[0] is the line number of the listview to be filled)
; Syntax ........: _PingParse($aTarget[, $bDomain = True])
; Parameters ....: $sTarget             - An array with Ping results passed by the MultiTasks as soon as any ping task ends
;                                         the passed array contains following data:
;                                         $aTarget[0] Index for this task
;                                         $aTarget[1] StdOut from ping (the whole output of the ping)
;                                         $aTarget[2] StdErr from ping
;                                         $aTarget[3] Time spent by this task to complete (is NOT the ping roundtrip time)
;                  $bDomain             - [optional] A binary value. Default is True. (keep domain info in host name)
;
; Return values .: None. It Fills Listview columns 0, 1 and 2
;                                         column 0 : resolved HostName or ""
;                                         column 1 : IP address or "" (this can contain last known IP even if now is offline)
;                                         column 2 : roundtrip time or "Unknown" or "timeout" or "Off"
;
; Author ........: Chimp
; ===============================================================================================================================
Func _PingParse($aTarget, $bDomain = True)
    ; $aTarget contains 4 elements: [0] Index, [1] StdOut, [2] StdErr, [3] time spent by this task

    Local $sOutput = $aTarget[1] ; stdout
    Local $0, $1, $2, $3, $aMs
    ; Local $iAnswer = -1, $iName = -1
    Local $aResult[3] = ["", "", ""] ; [0]ms, [1]HostName, [2]IP

    $aMs = StringRegExp($sOutput, "([0-9]*)ms", 3)
    If Not @error Then ; Ping replayed
        $aResult[0] = $aMs[UBound($aMs) - 1] ; average ms
    Else
        ; $aResult[0] = "off"
    EndIf

    $0 = StringInStr($sOutput, "Ping")
    $1 = StringInStr($sOutput, "[") ; HostName decoded?

    If $1 Then ; HostName decoded
        $2 = StringInStr($sOutput, "]")
        $3 = StringInStr($sOutput, " ", 0, -2, $1)
        $aResult[1] = StringMid($sOutput, $3 + 1, $1 - $3 - 1) ; HostName
        $aResult[2] = StringMid($sOutput, $1 + 1, $2 - $1 - 1) ; IP
    Else

        If $0 Then ; pinging an IP address?
            ; $aResult[1] = "" ; no HostName
            Local $aFindIP = StringRegExp($sOutput, "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", 3)
            If Not @error Then $aResult[2] = $aFindIP[0]
        Else
            ; unknown HostName
            $aResult[0] = "Unknown"
            $aResult[1] = $aIPList[$aTarget[0]] ; retrieve HostName from the $aIPList array

        EndIf
    EndIf

    If $bDomain = False Then
        Local $aSplit = StringSplit($aResult[1], ".", 2) ; 2 = $STR_NOCOUNT
        $aResult[1] = $aSplit[0] ; romove .domain part from the HostName
    EndIf

    If StringLeft($aTarget[2], 14) = "@error Timeout" Then $aResult[0] = "Timeout"

    ; Now that we have the infos, we compile related cells in ListView
    ;                            grid    row-handle            data         column
    _GUICtrlListView_SetItemText($hGrid, $ahGrid[$aTarget[0]], $aResult[1], 0) ;    first column "HostName"
    _GUICtrlListView_SetItemText($hGrid, $ahGrid[$aTarget[0]], $aResult[2], 1) ;    second column "IP address"
    _GUICtrlListView_SetItemText($hGrid, $ahGrid[$aTarget[0]], $aResult[0], 2) ;    third column "Infos about the ping"

    ; ConsoleWrite("Debug: " & "-> " & $aResult[0] & @TAB & $aResult[1] & @TAB & $aResult[2] & @CRLF)
EndFunc   ;==>_PingParse

Func _LastReboot($aParameters) ; Last reboot DateTime
    $aParameters[1] = StringStripWS($aParameters[1], 8)
    Local $equal = StringInStr($aParameters[1], "=")
    If $equal Then
        _GUICtrlListView_AddSubItem($hGrid, $ahGrid[$aParameters[0]], WMIDateStringToDate(StringMid($aParameters[1], $equal + 1)), 3) ; column 3
    EndIf
EndFunc   ;==>_LastReboot

Func _CPU_load($aParameters) ; % of CPU load
    $aParameters[1] = StringStripWS($aParameters[1], 8)
    Local $equal = StringInStr($aParameters[1], "=")
    If $equal Then
        _GUICtrlListView_AddSubItem($hGrid, $ahGrid[$aParameters[0]], StringMid($aParameters[1], $equal + 1), 4) ; column 4
    EndIf
EndFunc   ;==>_CPU_load

Func _LoggedOn($aParameters) ; User now logged
    $aParameters[1] = StringStripWS($aParameters[1], 8)
    ; if none is logged, then find the user that was last logged (also using _TaskRun)
    If $aParameters[1] = "" Or $aParameters[1] = "UserName=" Then
        ; following syntax is by @iamtheky (thanks)
        ; https://www.autoitscript.com/forum/topic/189845-regexp-pattern-in-findstr-dos-command/?do=findComment&comment=1363106
        Local $sCmd = 'cmd /c FOR /F "usebackq skip=2 tokens=1-3" %A IN (`REG QUERY ' & '"\\' & $aIPList[$aParameters[0]] & _
                '\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI" /REG:64 /v LastLoggedOnUser 2^>nul`) Do @echo %C'
        _TaskRun($aParameters[0], $sCmd, "_LastLogged", 5) ; find last logged user and, when ready, send result to _LastLogged()
    Else
        ; if someone is logged then write username to column 6
        Local $aUser = StringSplit($aParameters[1], "=", 2) ; 2 = $STR_NOCOUNT
        _GUICtrlListView_AddSubItem($hGrid, $ahGrid[$aParameters[0]], $aUser[UBound($aUser) - 1], 6) ; column 6
    EndIf
EndFunc   ;==>_LoggedOn

Func _LastLogged($aParameters)
    _GUICtrlListView_AddSubItem($hGrid, $ahGrid[$aParameters[0]], $aParameters[1], 5) ; column 5
EndFunc   ;==>_LastLogged


Func WMIDateStringToDate($dtmDate) ; thanks to @kylomas
    ; https://www.autoitscript.com/forum/topic/169252-wmi-password-age-issue/?do=findComment&comment=1236082
    ; reformat date to mm/dd/yyyy hh:mm:ss and zero fill single digit values
    Return StringRegExpReplace(StringRegExpReplace($dtmDate, '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}).*', '$2/$3/$1 $4:$5:$6'), '(?<!\d)(\d/)', '0$1')
EndFunc   ;==>WMIDateStringToDate

 

Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
KickStarter15
Posted (edited)

@Chimp

Indeed so awesome code you made! V-Nice....:D and thank you for sharing it to me. However, when I tried running your code, it replaced my IP address with invalid one which cause of slight issue in my Computer (lost connection). Also during the runtime of the script, it causes of slowness of my PC but it show's all the network IP addresses from my station, but usernames were not shown (except my own username).

The MultiPing.au3 replaces my IP with another IP. The MultiTask.au3 show's all IP's within the network.

Question: For MultiPing.au3, can you change it not to replace my IP address? not sure if I'm getting it right.

 

Thank you!

KS15

 

Edited by KickStarter15

Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare.

Share this post


Link to post
Share on other sites
Chimp

Hi @KickStarter15, the MultiPing.au3 functions are all in read mode and shouldn't act any change in your system. The slow down of your machine can be due to too many processes spawned by the MultiTask function, You can reduce a bit the spawned processes by commenting out lines that performs the remote reading of "lastbootuptime" and "loadpercentage" infos for example, or even better, I should implement in my udf a limit on the number of running processes at the same time.
... some wild guesses...
About the changed IP, do you have a system with static IP or with dhcp enabled? ....maybe your IP has been changed from some security system (?) in your network that detecting too many network activity against too many clients from your host interpreted it as malware attack (cutting out your client)??
About the lack of usernames retrieval, are you administrator on your system and also on the remote clients where you are trying to read info?


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
KickStarter15
7 minutes ago, Chimp said:

About the changed IP, do you have a system with static IP or with dhcp enabled? ....maybe your IP has been changed from some security system (?) in your network that detecting too many network activity against too many clients from your host interpreted it as malware attack (cutting out your client)??

Maybe you're right, I wasn't able to notice this when I tested your code. Hmmmm is there a way that I can revert it back to get my original IP?

11 minutes ago, Chimp said:

About the lack of usernames retrieval, are you administrator on your system and also on the remote clients where you are trying to read info?

I'm not the purely admin of our system but I have the access of some. Our IT is the administrator.:sweating: Even if not the admin, is there a way to get the usernames from that machine?

 

Thanks!

 


Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare.

Share this post


Link to post
Share on other sites
Chimp
16 minutes ago, KickStarter15 said:

Hmmmm is there a way that I can revert it back to get my original IP?

you should ask to a network administrator of you LAN  (.....I would not want to be in your shoes.... :sweating:)

 

16 minutes ago, KickStarter15 said:

Even if not the admin, is there a way to get the usernames from that machine?

I think not... you can even try, issue the following command from a dos prompt of your client and see if you get some "access denied" error or not...

wmic /node:hostname computersystem get username /value

change the hostname with the remote clientname or IP address you want would like to access...


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
orbs
Posted (edited)

it's all good and well when you have a ready-made UDF that does something similar to what you need... but sometimes scribbling your own script might prove more simple:

Global $sTargetIP, $sTargetName, $sTargetUser
For $iIP = 0 To 255
    $sTargetIP = '10.0.0.' & $iIP
    $sTargetName = RegRead('\\' & $sTargetIP & '\HKLM\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName', 'ComputerName')
    If @error Then
        ConsoleWrite('IP: ' & $sTargetIP & ' , RegRead() @error ' & @error & @CRLF)
        ContinueLoop
    EndIf
    $sTargetUser = RegRead('\\' & $sTargetIP & '\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI', 'LastLoggedOnUser')
    ConsoleWrite('IP: ' & $sTargetIP & ' , computer name: ' & $sTargetName & ' , user name: ' & $sTargetUser & @CRLF)
Next

notes:

1) NOT TESTED! but the logic should be easy to follow.

2) this method compensates for DHCP issues.

3) you can use WMI instead of registry reading if you see fit.

4) whatever method or opearation you perform, you MUST have access rights to the target machine. running as a domain admin is the simplest approach.

 

Edited by orbs

Share this post


Link to post
Share on other sites
KickStarter15
15 hours ago, Chimp said:

I think not... you can even try, issue the following command from a dos prompt of your client and see if you get some "access denied" error or not...

wmic /node:hostname computersystem get username /value

change the hostname with the remote clientname or IP address you want would like to access...

I got "Access is Denied" as a result.:( would this mean that only IP address can be gather and not their usernames?

 

@orbs

9 hours ago, orbs said:

4) whatever method or opearation you perform, you MUST have access rights to the target machine. running as a domain admin is the simplest approach.

I think it's the same with Chimps, I cant access the machines to get their usernames.


Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare.

Share this post


Link to post
Share on other sites
orbs

well, it's obvious you've got to resolve the access rights issue before trying any solution. what kind of a network is this? what inventory tools do you have?

Share this post


Link to post
Share on other sites
KickStarter15

@orbs,

I'm a little bit curious with the network and the inventory tool you mentioned. Can you elaborate more, kind of hanging in my head right now.:sweating:


Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare.

Share this post


Link to post
Share on other sites
orbs
2 hours ago, orbs said:

what kind of a network is this?

there are many types of network constellations, for example: AD domain, workgroup, ad-hoc laptops, servers farm, etc. the best methods to manage the network depends on that. for example, the wy to get access to remote targets is different in an AD domain and in a workgroup.

2 hours ago, orbs said:

what inventory tools do you have?

when you manage a network, you want to have an inventory of the computers. for computers, the simplest approach is an Excel file with a table of the following fields:

unique ID | hostname | hardware model | physical location | operating system | update level | etc...

this kind of a database is useful for all kinds of statistics and administration operations. for example, export the hostname column to a text file and feed it to a script running for all targets.

for more complex networks, you can have the table extended to include printers, servers, switches, and any kind of equipment.

the next step is to use a dedicated software for network inventory and administration, even one with a visual representation of the network, like this one. while you're at it, you can also monitor the targets, so you have a real-time overview of your network.

so basically, once you have the adequate tool to manage your network, tasks of such discussed in this topic become trivial.

Share this post


Link to post
Share on other sites
KickStarter15
42 minutes ago, orbs said:

there are many types of network constellations, for example: AD domain, workgroup, ad-hoc laptops, servers farm, etc. the best methods to manage the network depends on that. for example, the wy to get access to remote targets is different in an AD domain and in a workgroup.

Hmmm that's interesting, when you say AD domain does it mean your a single user from that network? I'm not in IT dept. but maybe I can be in a workgroup? Well, how would I know what network I am actually. There are many types of network we have here in our station, maybe that includes the type of network you've mentioned.

 

49 minutes ago, orbs said:

when you manage a network, you want to have an inventory of the computers. for computers, the simplest approach is an Excel file with a table of the following fields:

unique ID | hostname | hardware model | physical location | operating system | update level | etc...

I would rather use a text file as my database, there are some excel files in our station that is not functioning/working and need to purchase another version. So, other PCs in our station could not access excel file that would flag an error.


Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare.

Share this post


Link to post
Share on other sites
orbs

you may want to consult your IT about your network type, and methods to perform operations on remote targets. P.S. "AD" is an abbreviation for "Active Directory".
 

Share this post


Link to post
Share on other sites
KickStarter15

Thanks, @orbs... I'll check if IT dept. can provide me the things I need.:)

 

@Chimp,

Your code can store all IP addresses from the same network, is there a way that your code can determine if that specific IP is active or being shutdown?^_^


Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare.

Share this post


Link to post
Share on other sites
JLogan3o13

I would suggest looking at it (and talking to your Network Administration folks) from the opposite end. I have had this question from a number of customers, and usually suggest being proactive - create a group policy under logon scripts to record this information upon every login, and then output to somewhere that can be viewed by HelpDesk or other IT teams.

As an example, at one customer we named the GPO "WhoLoggedOn", a quick AutoIt script grabbed the following and wrote to a flat text file on all DCs:

FileWriteLine($WhoLoggedOn, @ComputerName & ", " & @UserName & ", " & @HOUR & ":" & @MIN & ":" & @SEC & ", " & @MON & "/" & @MDAY & ", " & @LogonServer & ", " & @IPAddress1 & ", " & $IEV & ", " & @OSVersion & ", " & @OSServicePack & ", " & ", " & $proc & ", " & @CPUArch)

For larger customers we used a small SQLite db. Either way, it is the matter of a couple of lines to write a parse script with a GUI for any techs that need to comb through this information.

 


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×