While most people won't need this I've been seeing threads requesting it lately.
A common problem is that the results of a query against a Jet MDB's active user roster via ADO and SCHEMA_ID_ROSTER returns database client user names and client machine names. But you let all users logon as Jet user "Admin." So you want to try to get Windows logon user names from the machine names.
What NetWkstaUserEnum Does
NetWkstaUserEnum() is a function used to get a list of logged on users at a machine by name. You can also pass it an empty name to get the local machine's logged on users.
This function actually enumerates the user logons and not the users. This includes interactive logons, batch logons, and service logons, so it frequently returns the same name more than once. Since in the course of normal use various system services will impersonate a user to perform functions on their behalf, so a user may be reported even if they have subsequently logged off their interactive session.
There are two "call levels" and Level 1 returns a few additional items most programs won't need.
What WkstaUserEnum.bas Does
This module exposes the EnumUsers() function. This makes Level 0 NetWkstaUserEnum() calls to build a list of user names in the dynamic String array passed to it. As it builds the list it eliminates duplicate entries, making it slightly more useful than some wrapper code I've seen.
You could use Level 1 calls instead if you want the extra info but these additional items aren't too exciting or useful to most programs. If you want this you'll need to decide how to return it, and you may want to eliminate the "duplicate filtering" since the multiple entries for the same user name may not really be unique (others values might vary).
Why Use WkstaUserEnum?
Yes, you can get this information via WMI queries. However WMI is not meant for use in applications, it is an admin scripting tool. It is also fairly "heavy" and depends on the WMI service being installed and running on the local machine and all target systems being queried.
Practical Issues
NetWkstaUserEnum() calls block, and so when querying a remote system there can be delays of many seconds. This is usually because the network is very slow, the remote system is very busy, or the remote system is an oddball device running Samba or something rather than actually being a Windows system.
It also only works for systems that are Windows NT 3.1 or later, or those with a good LAN Manager/MS Networking emulation.
The results returned are a list and may well have multiple user names in most realistic scenarios. It is possible that the first returned result tends to be that of the local console interactive logon (if any) but there are no guarantees. After all, there could be batch logons active with nobody logged on interactively at all!
Requirements
The querying system (running your program) must be Windows NT 4.0 or later. Queried systems should be Windows NT 3.1 or later.
There is no support for Win9x systems at either end.
Usage, Demo
The attached demo shows how easy it is to use. Here is all of the code in the demo's Form1:
A common problem is that the results of a query against a Jet MDB's active user roster via ADO and SCHEMA_ID_ROSTER returns database client user names and client machine names. But you let all users logon as Jet user "Admin." So you want to try to get Windows logon user names from the machine names.
What NetWkstaUserEnum Does
NetWkstaUserEnum() is a function used to get a list of logged on users at a machine by name. You can also pass it an empty name to get the local machine's logged on users.
This function actually enumerates the user logons and not the users. This includes interactive logons, batch logons, and service logons, so it frequently returns the same name more than once. Since in the course of normal use various system services will impersonate a user to perform functions on their behalf, so a user may be reported even if they have subsequently logged off their interactive session.
There are two "call levels" and Level 1 returns a few additional items most programs won't need.
What WkstaUserEnum.bas Does
This module exposes the EnumUsers() function. This makes Level 0 NetWkstaUserEnum() calls to build a list of user names in the dynamic String array passed to it. As it builds the list it eliminates duplicate entries, making it slightly more useful than some wrapper code I've seen.
You could use Level 1 calls instead if you want the extra info but these additional items aren't too exciting or useful to most programs. If you want this you'll need to decide how to return it, and you may want to eliminate the "duplicate filtering" since the multiple entries for the same user name may not really be unique (others values might vary).
Why Use WkstaUserEnum?
Yes, you can get this information via WMI queries. However WMI is not meant for use in applications, it is an admin scripting tool. It is also fairly "heavy" and depends on the WMI service being installed and running on the local machine and all target systems being queried.
Practical Issues
NetWkstaUserEnum() calls block, and so when querying a remote system there can be delays of many seconds. This is usually because the network is very slow, the remote system is very busy, or the remote system is an oddball device running Samba or something rather than actually being a Windows system.
It also only works for systems that are Windows NT 3.1 or later, or those with a good LAN Manager/MS Networking emulation.
The results returned are a list and may well have multiple user names in most realistic scenarios. It is possible that the first returned result tends to be that of the local console interactive logon (if any) but there are no guarantees. After all, there could be batch logons active with nobody logged on interactively at all!
Requirements
The querying system (running your program) must be Windows NT 4.0 or later. Queried systems should be Windows NT 3.1 or later.
There is no support for Win9x systems at either end.
Usage, Demo
The attached demo shows how easy it is to use. Here is all of the code in the demo's Form1:
Code:
Option Explicit
Private Sub cmdFetch_Click()
Dim Status As NETAPI_STATUSES
Dim strUsers() As String
Dim I As Long
Status = WkstaUserEnum.EnumUsers(txtServer.Text, strUsers)
If Status = NERR_SUCCESS Then
With txtResult
.Text = ""
For I = 0 To UBound(strUsers)
.SelText = strUsers(I)
.SelText = vbNewLine
Next
End With
ElseIf Status = EXTENDED_EXCEPTION Then
txtResult.Text = "VB Exception " & CStr(WkstaUserEnum.LastError) & " " _
& WkstaUserEnum.LastDescription
Else
txtResult.Text = "System Error " & CStr(WkstaUserEnum.LastError) & " " _
& WkstaUserEnum.LastDescription
End If
txtServer.SetFocus
End Sub