Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Q. for Sys Admins: how programmatically find User Names currently logged onto a network server?

Status
Not open for further replies.

IlyaRabyy

Programmer
Nov 9, 2010
568
US
Colleagues,
The subject line says it.
I hope there is at least one Sys Admin among you?

AHWBGA!

Regards,

Ilya
 
You want a list of every user currently logged in to the domain? Sadly (and perhaps surprisingly) AD does not track this info. Or just those users logged on to a particular server? If the latter, then something like

Code:
[COLOR=blue]        Dim searcher As New ManagementObjectSearcher("\\yourservername\root\cimv2", "SELECT * FROM Win32_ComputerSystem")
        Dim queryCollection As ManagementObjectCollection = searcher.Get()

        For Each queryObj As ManagementObject In queryCollection
            MsgBox($"Logged in user: {queryObj("UserName")}")
        Next[/color]

You need to import [tt]System.Management[/tt] (and it is possible you will first have to add this package through NuGet)
 
2024-03-27_ManagementObjectSearcher_Is_Not_Defined_xd5v9p.jpg


Regards,

Ilya
 
As I said: "it is possible you will first have to add this package through NuGet
 
Alrite, I found and added System.Management package to the Project.
Code:
Code:
Dim searcher As New ManagementObjectSearcher("\\yourservername\root\cimv2", "SELECT * FROM Win32_ComputerSystem")
Dim queryCollection As ManagementObjectCollection = searcher.Get()

erred:

2024-04-08_CommonSubs_Error_e00vku.jpg


The MS Help at isn't much of a help...

[banghead]

What else am I missing?

Regards,

Ilya
 
Er... You need to replace [tt]yourservername[/tt] with the actual name of your server ...
 
Done.
(Well, not server but my own WS, its name's redacted.)

Code:
Dim searcher As New ManagementObjectSearcher("\\XXXXXXXXXXXXX\root", "SELECT * FROM Win32_ComputerSystem") ' \\An2PreODSApp001\root\cimv2
Dim queryCollection As ManagementObjectCollection = searcher.Get()
Dim lsLogStr As String = ""

For Each queryObj As ManagementObject In queryCollection
'	MsgBox($"Logged in user: {queryObj("UserName")}")
	lsLogStr += queryObj.ToString() + vbCrLf
Next
Errs on Next:

2024-04-08_CommonSubs_Error_2_fry7km.jpg


I would understand if it erred on lsLogStr += statement, but on Next... [ponder]

Regards,

Ilya
 
>I would understand
Essentially you are trying to enumerate an empty ManagementObjectCollection (because you edited the search scope incorrectly). Thus [tt]Next[/tt] fails, since there is nothing to enumerate (this is a simplified explanation)

Mind you, when you DO get the emnumeration working then I don't think that lsLogStr will contain what yyou think, as you are converting an entire object to a displayable string, and not just the Username


Code:
[COLOR=blue]Dim searcher As New ManagementObjectSearcher("\\YOURSERVERNAME\root[b][COLOR=red]\cimv2[/color][/b]", "SELECT * FROM Win32_ComputerSystem") ' 
Dim queryCollection As ManagementObjectCollection = searcher.Get()
Dim lsLogStr As String = ""

For Each queryObj As ManagementObject In queryCollection
    lsLogStr += [b][COLOR=red]queryObj("UserName").ToString() + vbCrLf[/color][/b]
Next[/color]
 
Adding "\cimv2" worked, but it returned only the name of my W/S.
Well, obviously, coz I test it on my W/S.
But it doesn't list my UN...
Currently, I have this code (in my test program):

Code:
Dim searcher As New ManagementObjectSearcher("\\XXXXXXXXX\root\[COLOR=#CC0000][b]cimv2[/b][/color]", _
					"SELECT * FROM Win32_ComputerSystem")
Dim queryCollection As ManagementObjectCollection = searcher.Get()
Dim lsLogStr As String = ""

For Each queryObj As ManagementObject In queryCollection
	lsLogStr += queryObj.ToString() + vbCrLf
Next

2024-04-09_CommonSubs_ManagementObject_01_f7czfs.jpg


What else am I missing?

On the footnote: I've always been End User/Desktop Applications programmer, never System Programmer, all this stuff is totally new to me! So I truly appreciate your patience, Master StrongM! (No pun intended whatsoever, I'm dead serious!)

Regards,

Ilya
 
You didn't apply all my corrections, so what you are returning is 1) indeed not the username but 2) neither is it the W/S name. What your are returning, as previously explained, is the stringified name of the object you are using (a specific instance of the WMI Win32_ComputerSystem class - this string may look somewhat like your W/S name, but actually is not). Look at my code again, and use the second correction in red as well as the first.
 
Rite!
queryObj("UserName") did the trick! (My apologies, I've overlooked it...)
Thank you!

Regards,

Ilya
 
Here's the function I programmed based on the StrongM's recommendations.
Please review and advise: have I missed anything still (especially in the parameter verification part)?
Code:
'====================================================================================================================================
Public Function GetUserNames(ByVal tcMachineName) As String
'====================================================================================================================================
' Purpose       : Returns the list of the User Names currently logged into the givem machine.
' Description   : Engages ManagementObject[Collection] class[es] to query system logs for the currently logged in User Names.
' Parameters	: The Machine name.
' Returns	: List of the User Names, separated by CRLF, currently logged into the given machine.
' Side effects  : None.
' Notes         : 1. Generic.
'                 2. Complies with .NET Framework ver. 1.1 and higher.
'		  3. On error, returns the error description, which starts with "Error occurred" phrase.
' Author        : Ilya I. Rabyy
' Revisions     : by Ilya on 2024-04-09 - started 1st draft.
'====================================================================================================================================
Dim lsLogStr As String = ""

' Parameter verification
If (TypeOf tcMachineName IsNot String) Then
	lsLogStr = "Error occurred: the Machine Name parameter is not of type String!"
	Return lsLogStr
End If

Dim lcMachineName As String = Strings.Trim(tcMachineName)

If String.IsNullOrEmpty(lcMachineName) Then
	lsLogStr = "Error occurred: the Machine Name parameter must not be empty!"
	Return lsLogStr
End If

' Format the Machine Name
If Not Left(lcMachineName, 2) = "\\" Then
	
	If Not Left(lcMachineName, 1) = "\" Then
		lcMachineName = "\\" + lcMachineName
	Else
		lcMachineName = "\" + lcMachineName
	End If ' Not Left(lcMachineName, 1) = "\"

End If ' Not Left(lcMachineName, 2) = "\\"

lcMachineName = AddBackSlash(lcMachineName)

' Parameter's been validated (it seems).
' Let's get digging! But keep in mind that if it's a network server, it might be unavailable, hence Try-Catch-EndTry construct.
Try
	Dim loSearcher As New ManagementObjectSearcher(lcMachineName + "root\cimv2", "SELECT * FROM Win32_ComputerSystem")
	Dim loQueryCollection As ManagementObjectCollection = loSearcher.Get()

	For Each loQueryObj As ManagementObject In loQueryCollection
		lsLogStr += loQueryObj("UserName").ToString() + vbCrLf
	Next
Catch loErr As Exception
	lsLogStr = Read_Exception(loErr)
End Try

Return lsLogStr

End Function
'====================================================================================================================================

Regards,

Ilya
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top