Pour obtenir une liste de tous les utilisateurs d'un domaine de Windows NT ou 2000, on peut utiliser la fonction API NetUserEnum.
Même si plusieurs niveaux de détails sont disponibles, le nom de l'utilisateur est présent dès le niveau de base, soit de la structure USER_INFO_0. La structure USER_INFO_2 retourne beaucoup plus d'information sur un compte d'utilisateur spécifique..
Une simple fonction couvrant ces deux niveaux, de par l'utilisation de l'API, est présentée ci-dessous. Prière de noter que ces fonctions ne sont disponibles que pour NT ou 2000 seulement.
Source / Exemple :
' Level 0 - Ne retourne que le nom des comptes...
' The bufptr parameter (NetUserEnum) points to
' an array of USER_INFO_0 structures.
Private Type USER_INFO_0
usri0_name As Long
End Type
' structure contains information about a user account, including
' the account name, password data, privilege level, the path
' to the user's home directory, and other user-related
' network statistics. Level 2 call
Private Type USER_INFO_2
usri2_name As Long
usri2_password As Long ' Null, only settable
usri2_password_age As Long
usri2_priv As Long
usri2_home_dir As Long
usri2_comment As Long
usri2_flags As Long
usri2_script_path As Long
usri2_auth_flags As Long
usri2_full_name As Long
usri2_usr_comment As Long
usri2_parms As Long
usri2_workstations As Long
usri2_last_logon As Long
usri2_last_logoff As Long
usri2_acct_expires As Long
usri2_max_storage As Long
usri2_units_per_week As Long
usri2_logon_hours As Long
usri2_bad_pw_count As Long
usri2_num_logons As Long
usri2_logon_server As Long
usri2_country_code As Long
usri2_code_page As Long
End Type
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Private Type TIME_ZONE_INFORMATION
Bias As Long
StandardName(0 To 63) As Byte
StandardDate As SYSTEMTIME
StandardBias As Long
DaylightName(0 To 63) As Byte
DaylightDate As SYSTEMTIME
DaylightBias As Long
End Type
' function provides information about all user
' accounts on a server
Private Declare Function apiNetUserEnum _
Lib "netapi32.DLL" Alias "NetUserEnum" _
(ByVal servername As Long, _
ByVal level As Long, _
ByVal filter As Long, _
bufptr As Long, _
ByVal prefmaxlen As Long, _
entriesread As Long, _
totalentries As Long, _
resume_handle As Long) _
As Long
Private Declare Function apiNetUserEnum _
Lib "netapi32.DLL" Alias "NetUserEnum" _
(ByVal servername As Long, _
ByVal level As Long, _
ByVal filter As Long, _
bufptr As Long, _
ByVal prefmaxlen As Long, _
entriesread As Long, _
totalentries As Long, _
resume_handle As Long) _
As Long
' function frees the memory that the NetApiBufferAllocate
' function allocates.
Private Declare Function apiNetAPIBufferFree _
Lib "netapi32.DLL" Alias "NetApiBufferFree" _
(ByVal buffer As Long) _
As Long
' Retrieves the length of the specified wide string.
Private Declare Function apilstrlenW _
Lib "kernel32" Alias "lstrlenW" _
(ByVal lpString As Long) _
As Long
' moves memory either forward or backward, aligned or unaligned,
' in 4-byte blocks, followed by any remaining bytes
Private Declare Sub sapiCopyMem _
Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)
'function retrieves the current time-zone parameters. These
'parameters control the translations between Coordinated
'Universal Time (UTC) and local time.
Private Declare Function apiGetTZI Lib "kernel32" _
Alias "GetTimeZoneInformation" _
(lpTimeZoneInformation As TIME_ZONE_INFORMATION) _
As Long
' Enumerates local user account data on a domain controller.
Private Const FILTER_TEMP_DUPLICATE_ACCOUNT = &H1&
' Enumerates global user account data on a computer.
Private Const FILTER_NORMAL_ACCOUNT = &H2&
' Enumerates domain trust account data on a domain controller.
Private Const FILTER_INTERDOMAIN_TRUST_ACCOUNT = &H8&
' Enumerates workstation or member server account data on a
' domain controller.
Private Const FILTER_WORKSTATION_TRUST_ACCOUNT = &H10&
' Enumerates domain controller account data on a domain controller.
Private Const FILTER_SERVER_TRUST_ACCOUNT = &H20&
Private Const MAX_PREFERRED_LENGTH = -1&
Private Const NERR_SUCCESS = 0
' More entries are available. Specify a large enough
' buffer to receive all entries.
Private Const ERROR_MORE_DATA = 234&
' Privileges
Private Const USER_PRIV_GUEST = 0&
Private Const USER_PRIV_USER = 1&
Private Const USER_PRIV_ADMIN = 2&
'GetTimeZoneInformation Return values
Private Const TIME_ZONE_ID_INVALID = &HFFFFFFFF
Private Const TIME_ZONE_ID_UNKNOWN = 0
Private Const TIME_ZONE_ID_STANDARD = 1
Private Const TIME_ZONE_ID_DAYLIGHT = 2
' User Flags
Private Const UF_SCRIPT = &H1
Private Const UF_ACCOUNTDISABLE = &H2
Private Const UF_HOMEDIR_REQUIRED = &H8
Private Const UF_LOCKOUT = &H10
Private Const UF_PASSWD_NOTREQD = &H20
Private Const UF_PASSWD_CANT_CHANGE = &H40
Private Const UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = &H80
Private Const UF_DONT_EXPIRE_PASSWD = &H10000
Private Const UF_MNS_LOGON_ACCOUNT = &H20000
Private Const UF_SMARTCARD_REQUIRED = &H40000
Private Const UF_TRUSTED_FOR_DELEGATION = &H80000
Private Const UF_NOT_DELEGATED = &H100000
Private Const UF_USE_DES_KEY_ONLY = &H200000
Private Const UF_DONT_REQUIRE_PREAUTH = &H400000
Private Const UF_TEMP_DUPLICATE_ACCOUNT = &H100
Private Const UF_NORMAL_ACCOUNT = &H200
Private Const UF_INTERDOMAIN_TRUST_ACCOUNT = &H800
Private Const UF_WORKSTATION_TRUST_ACCOUNT = &H1000
Private Const UF_SERVER_TRUST_ACCOUNT = &H2000
Function fEnumDomainUsers_Level2( _
Optional strServerName As String) _
As Boolean
' -------------------------------
' NT / WIN2000 ONLY
' -------------------------------
' Enumerates all Global accounts on a NT
' server, LEVEL_2
' if len(strServerName)=0,
' assume local machine
'
On Error GoTo ErrHandler
Dim abytServerName() As Byte
Dim pBuf As Long
Dim pTmpBuf As USER_INFO_2
Dim dwLevel As Long
Dim dwPrefMaxLen As Long
Dim dwEntriesRead As Long
Dim dwTotalEntries As Long
Dim dwResumeHandle As Long
Dim i As Long
Dim dwTotalCount As Long
Dim nStatus As Long
' assume MAX_PREFERRED_LENGTH
dwPrefMaxLen = MAX_PREFERRED_LENGTH
abytServerName = strServerName & vbNullChar
dwLevel = 2 ' Level 2 call
Do
'only global users
nStatus = apiNetUserEnum(VarPtr(abytServerName(0)), _
dwLevel, _
FILTER_NORMAL_ACCOUNT, _
pBuf, _
dwPrefMaxLen, _
dwEntriesRead, _
dwTotalEntries, _
dwResumeHandle)
' If the call succeeds,
If ((nStatus = NERR_SUCCESS) Or (nStatus = ERROR_MORE_DATA)) Then
' Loop through the entries.
For i = 0 To dwEntriesRead - 1
Call sapiCopyMem( _
pTmpBuf, _
ByVal (pBuf + (i * 96)), _
Len(pTmpBuf)) ' 96=len(USER_INFO_2)
With pTmpBuf
' Print the name of the user account.
Debug.Print "Name : ", fStrFromPtrW(.usri2_name)
' password is Null when reading the info, obviously!
' flags
Debug.Print "Account Info: "
Call sPrintAccountInfo(.usri2_flags)
' password_age
Debug.Print "Number of seconds since the " _
& "password was last changed: ", .usri2_password_age
' Privilege
Debug.Print "Level of Privilege: ",
Select Case .usri2_priv
Case USER_PRIV_GUEST
Debug.Print "Guest"
Case USER_PRIV_USER
Debug.Print "User"
Case USER_PRIV_ADMIN
Debug.Print "Admin"
End Select
' Home Directory
Debug.Print "Home Directory: ", fStrFromPtrW(.usri2_home_dir)
' Comment
Debug.Print "Comment: ", fStrFromPtrW(.usri2_comment)
' Script Path
Debug.Print "Script Path: ", fStrFromPtrW(.usri2_script_path)
' user's operator privileges
' Full Name
Debug.Print "Full Name: ", fStrFromPtrW(.usri2_full_name)
' User Comment
Debug.Print "User Comment: ", fStrFromPtrW(.usri2_usr_comment)
' Parms for Apps
Debug.Print "Params for Apps: ", fStrFromPtrW(.usri2_parms)
' Workstations from which user can log on (max 8)
Debug.Print "Workstations from which user can log on: ", _
fStrFromPtrW(.usri2_workstations)
' when the last logon occurred
Debug.Print "Last Logon occurred at: ", fGetTime(.usri2_last_logon)
' when the last logoff occurred
Debug.Print "Last Logoff occurred at: ", fGetTime(.usri2_last_logoff)
' when the account expires
Debug.Print "Account Expires on: ", fGetTime(.usri2_acct_expires)
' Max disk space user can use
Debug.Print "Max Disk Space allotted: ", .usri2_max_storage
' Units per week
Debug.Print "Units per week: ", .usri2_units_per_week
' Logon Hours 21-byte (168 bits) bit string
Debug.Print "Logon Hours: ", .usri2_logon_hours
' Bad password count
Debug.Print "Bad password count: ", .usri2_bad_pw_count
' Number of successful logons
Debug.Print "Number of successful logons: ", .usri2_num_logons
' Logon Server
Debug.Print "Logon Server: ", fStrFromPtrW(.usri2_logon_server)
' Country Code
Debug.Print "Country Code: ", .usri2_country_code
' Code Page
Debug.Print "Code Page: ", .usri2_code_page
End With
' Keep a count of accounts enumerated
dwTotalCount = dwTotalCount + 1
Debug.Print "--------------------------------"
Next
End If
' free the associated memory
Call apiNetAPIBufferFree(pBuf)
pBuf = 0
Loop While (nStatus = ERROR_MORE_DATA)
If Not (pBuf = 0) Then Call apiNetAPIBufferFree(pBuf)
fEnumDomainUsers_Level2 = True
ExitHere:
Exit Function
ErrHandler:
fEnumDomainUsers_Level2 = False
Resume ExitHere
End Function
Function fEnumDomainUsers( _
Optional strServerName As String) _
As Boolean
' -------------------------------
' NT / WIN2000 ONLY
' -------------------------------
' Enumerates all Global accounts on a NT
' server, LEVEL_0
' if len(strServerName)=0,
' assume local machine
'
On Error GoTo ErrHandler
Dim abytServerName() As Byte
Dim pBuf As Long
Dim pTmpBuf As USER_INFO_0
Dim dwLevel As Long
Dim dwPrefMaxLen As Long
Dim dwEntriesRead As Long
Dim dwTotalEntries As Long
Dim dwResumeHandle As Long
Dim i As Long
Dim dwTotalCount As Long
Dim nStatus As Long
' assume MAX_PREFERRED_LENGTH
dwPrefMaxLen = MAX_PREFERRED_LENGTH
abytServerName = strServerName & vbNullChar
dwLevel = 0 ' Level 0 call
Do
'only global users
nStatus = apiNetUserEnum(VarPtr(abytServerName(0)), _
dwLevel, _
FILTER_NORMAL_ACCOUNT, _
pBuf, _
dwPrefMaxLen, _
dwEntriesRead, _
dwTotalEntries, _
dwResumeHandle)
' If the call succeeds,
If ((nStatus = NERR_SUCCESS) Or (nStatus = ERROR_MORE_DATA)) Then
' Loop through the entries.
For i = 0 To dwEntriesRead - 1
Call sapiCopyMem( _
pTmpBuf, _
ByVal (pBuf + (i * 4)), _
Len(pTmpBuf)) ' 4=len(USER_INFO_0)
' Print the name of the user account.
Debug.Print fStrFromPtrW(pTmpBuf.usri0_name)
' Keep a count of accounts enumerated
dwTotalCount = dwTotalCount + 1
Next
End If
' free the associated memory
Call apiNetAPIBufferFree(pBuf)
pBuf = 0
Loop While (nStatus = ERROR_MORE_DATA)
If Not (pBuf = 0) Then Call apiNetAPIBufferFree(pBuf)
fEnumDomainUsers = True
ExitHere:
Exit Function
ErrHandler:
fEnumDomainUsers = False
Resume ExitHere
End Function
Private Sub sPrintAccountInfo(lngFlags As Long)
' Prints out details about an account
If lngFlags And UF_ACCOUNTDISABLE Then
Debug.Print Space$(5), "Account is disabled."
End If
If lngFlags And UF_HOMEDIR_REQUIRED Then
Debug.Print Space$(5), "Home Direcotory is required."
End If
If lngFlags And UF_PASSWD_NOTREQD Then
Debug.Print Space$(5), "No password is required."
End If
If lngFlags And UF_PASSWD_CANT_CHANGE Then
Debug.Print Space$(5), "The user cannot change the password."
End If
If lngFlags And UF_LOCKOUT Then
Debug.Print Space$(5), "The account is currently locked out."
End If
If lngFlags And UF_DONT_EXPIRE_PASSWD Then
Debug.Print Space$(5), "The password should never expire on the account."
End If
If lngFlags And UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED Then
Debug.Print Space$(5), "The User 's password is stored " _
& "under reversible encryption in the Active Directory."
End If
If lngFlags And UF_NOT_DELEGATED Then
Debug.Print Space$(5), "Sensitive account; other " _
& "users cannot act as delegates of this user account."
End If
If lngFlags And UF_SMARTCARD_REQUIRED Then
Debug.Print Space$(5), "Smart card is required to log on."
End If
If lngFlags And UF_DONT_REQUIRE_PREAUTH Then
Debug.Print Space$(5), "This account does not require " _
& "Kerberos preauthentication for logon."
End If
If lngFlags And UF_TRUSTED_FOR_DELEGATION Then
Debug.Print Space$(5), "The account is enabled for delegation."
End If
If lngFlags And UF_SCRIPT Then
Debug.Print Space$(5), "The logon script executed. "
End If
If lngFlags And UF_NORMAL_ACCOUNT Then
Debug.Print Space$(5), "This is a default account " _
& "type that represents a typical user."
End If
If lngFlags And UF_TEMP_DUPLICATE_ACCOUNT Then
Debug.Print Space$(5), "This is an account for users " _
& "whose primary account is in another domain. "
End If
If lngFlags And UF_WORKSTATION_TRUST_ACCOUNT Then
Debug.Print Space$(5), "This is a computer account for a " _
& "Windows NT/Windows 2000 workstation or Windows " _
& "NT/Windows 2000 server that is a member of this domain."
End If
If lngFlags And UF_SERVER_TRUST_ACCOUNT Then
Debug.Print Space$(5), "This is a computer account for a " _
& "backup domain controller that is a member of this domain."
End If
If lngFlags And UF_INTERDOMAIN_TRUST_ACCOUNT Then
Debug.Print Space$(5), "This is a permit to trust account for " _
& " a domain that trusts other domains."
End If
End Sub
Private Function fGetTime(ByVal lngSeconds As Long) As Variant
Dim lpTZI As TIME_ZONE_INFORMATION
Dim lngRet As Long
Const START_DATE = "01/01/1970 00:00:00"
' Get the TimeZone Information
lngRet = apiGetTZI(lpTZI)
' if the function succeeded
If Not lngRet = TIME_ZONE_ID_INVALID Then
With lpTZI
' calculate offset from START_DATE
fGetTime = DateAdd("s", lngSeconds - (.Bias * 60) _
- (.DaylightBias * 60), _
CDate(START_DATE))
End With
End If
End Function
Private Function fStrFromPtrW(pBuf As Long) As String
Dim lngLen As Long
Dim abytBuf() As Byte
' Get the length of the string at the memory location
lngLen = apilstrlenW(pBuf) * 2
' if it's not a ZLS
If lngLen Then
ReDim abytBuf(lngLen)
' then copy the memory contents
' into a temp buffer
Call sapiCopyMem( _
abytBuf(0), _
ByVal pBuf, _
lngLen)
' return the buffer
fStrFromPtrW = abytBuf
End If
End Function
Conclusion :
Auteur : Dev Ashish
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.