Question:
Is there a way to pass in a local workstation's host name and get a return of a list of the local administrators for that workstation? I have seen this in the Hyena program and wanted to do the same from VB5/VB6 code.
Answer:
On a form with a command button and a listbox, paste the following code:
Private Sub Command1_Click()
Dim vntRtn As Variant
Dim lngNumItems As Long
Dim lngLoop As Long
Me.List1.Clear
vntRtn = Module1.GetAdminUsers("PDCNEW")
On Error Resume Next
lngNumItems = UBound(vntRtn)
On Error GoTo 0
If lngNumItems > 0 Then
For lngLoop = 1 To lngNumItems
Me.List1.AddItem vntRtn(lngLoop)
Next lngLoop
End If
End Sub
In a BAS file called Module1, paste the following code:
Option Explicit
Private Declare Function NetUserEnum _
Lib "netapi32" _
(abytServer As Byte, _
ByVal Level As Long, _
ByVal Flags As Long, _
lngBuffer As Long, _
ByVal MaxLen As Long, _
lpEntriesRead As Long, _
lpTotalEntries As Long, _
lpResume_Handle As Long) As Long
Private Declare Function NetApiBufferFree _
Lib "netapi32" _
(ByVal pBuffer As Long) As Long
Private Declare Sub CopyMem _
Lib "kernel32" Alias "RtlMoveMemory" _
(pTo As Any, _
uFrom As Any, _
ByVal lSize As Long)
Private Declare Function lstrlenW _
Lib "kernel32" _
(ByVal lpString As Long) As Long
Private Declare Function lstrlen _
Lib "kernel32" _
(ByVal lpString As Long) As Long
Private Const USER_PRIV_GUEST As Long = &H0
Private Const USER_PRIV_USER As Long = &H1
Private Const USER_PRIV_ADMIN As Long = &H2
Private Const constUserInfo1 As Long = 1
Private Type USER_INFO_1_API
usri1_name As Long
usri1_password As Long
usri1_password_age As Long
usri1_priv As Long
usri1_home_dir As Long
usri1_comment As Long
usri1_flags As Long
usri1_script_path As Long
End Type
Private Type USER_INFO_1
usri1_name As String
usri1_password As Long
usri1_password_age As Long
usri1_priv As Long
usri1_home_dir As String
usri1_comment As String
usri1_flags As Long
usri1_script_path As String
End Type
Private Const NERR_Success As Long = 0&
Private Const ERROR_MORE_DATA As Long = 234&
Public Function GetAdminUsers(Optional ByVal xi_strServer As String) As Variant
Dim lngBuffer As Long
Dim abytServer() As Byte
Dim atypUsers() As USER_INFO_1_API
Dim astrAdmins() As String
Dim strName As String
Dim lngTotalUsers As Long
Dim lngTotalUsersRead As Long
Dim lngRtn As Long
Dim lngResumeHwnd As Long
Dim lngNumAdmins As Long
Dim lngLevel As Long
Dim lngLoop As Long
Const Flags& = 0
If Len(xi_strServer) = 0 Then
abytServer = ""
Else
If InStr(1, xi_strServer, "\\", vbTextCompare) <= 0 Then
xi_strServer = "\\" & xi_strServer
Else
' Already OK
End If
abytServer = xi_strServer & vbNullChar
End If
'call API to Enumerate users
If Len(xi_strServer) <> 0 Then
lngRtn = NetUserEnum(abytServer(0), constUserInfo1, _
Flags, lngBuffer, _
&H4000, lngTotalUsersRead, _
lngTotalUsers, lngResumeHwnd)
Else
lngRtn = NetUserEnum(ByVal 0&, constUserInfo1, _
Flags, lngBuffer, _
&H4000, lngTotalUsersRead, _
lngTotalUsers, lngResumeHwnd)
End If
If lngTotalUsersRead > 0 Then
ReDim atypUsers(0 To lngTotalUsersRead - 1)
CopyMem atypUsers(0), _
ByVal lngBuffer, _
Len(atypUsers(0)) * lngTotalUsersRead
lngLoop = 0
lngNumAdmins = 0
For lngLoop = 0 To lngTotalUsers - 1
strName = PointerToStringW(atypUsers(lngLoop).usri1_name)
lngLevel = atypUsers(lngLoop).usri1_priv
If lngLevel = USER_PRIV_ADMIN Then
lngNumAdmins = lngNumAdmins + 1
ReDim Preserve astrAdmins(1 To lngNumAdmins)
astrAdmins(lngNumAdmins) = strName
End If
Next lngLoop
End If
' Set the return value
GetAdminUsers = astrAdmins
If lngBuffer Then
NetApiBufferFree lngBuffer
End If
End Function
Private Function PointerToStringW(lpStringW As Long) As String
Dim Buffer() As Byte
Dim nLen As Long
If lpStringW Then
nLen = lstrlenW(lpStringW) * 2
If nLen Then
ReDim Buffer(0 To (nLen - 1)) As Byte
CopyMem Buffer(0), ByVal lpStringW, nLen
PointerToStringW = Buffer
End If
End If
End Function