KickStarter15 Posted February 28, 2018 Share Posted February 28, 2018 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. Link to comment Share on other sites More sharing options...
orbs Posted February 28, 2018 Share Posted February 28, 2018 @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. Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
Gianni Posted February 28, 2018 Share Posted February 28, 2018 (edited) 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 expandcollapse popup; #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 February 28, 2018 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
KickStarter15 Posted March 1, 2018 Author Share Posted March 1, 2018 (edited) @Chimp Indeed so awesome code you made! V-Nice.... 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 March 1, 2018 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. Link to comment Share on other sites More sharing options...
Gianni Posted March 1, 2018 Share Posted March 1, 2018 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? Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
KickStarter15 Posted March 1, 2018 Author Share Posted March 1, 2018 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. 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. Link to comment Share on other sites More sharing options...
Gianni Posted March 1, 2018 Share Posted March 1, 2018 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.... ) 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... Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
orbs Posted March 1, 2018 Share Posted March 1, 2018 (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 March 1, 2018 by orbs Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
KickStarter15 Posted March 2, 2018 Author Share Posted March 2, 2018 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. Link to comment Share on other sites More sharing options...
orbs Posted March 2, 2018 Share Posted March 2, 2018 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? Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
KickStarter15 Posted March 2, 2018 Author Share Posted March 2, 2018 @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. 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. Link to comment Share on other sites More sharing options...
orbs Posted March 2, 2018 Share Posted March 2, 2018 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. Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
KickStarter15 Posted March 2, 2018 Author Share Posted March 2, 2018 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. Link to comment Share on other sites More sharing options...
orbs Posted March 2, 2018 Share Posted March 2, 2018 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". Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
KickStarter15 Posted March 3, 2018 Author Share Posted March 3, 2018 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. Link to comment Share on other sites More sharing options...
Moderators JLogan3o13 Posted March 3, 2018 Moderators Share Posted March 3, 2018 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. "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum! 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