devxlogo

NT Server Local Groups

NT Server Local Groups

Question:
I would like to be able to gain access to NT server local groups for enum, member enum, add member, delete member.

We have a lot of servers as well as NT and OS/2 domains. Because of this, there is a need to synchronize users and group memberships across multiple servers.

I have not found anything that will allow me to access a local group on a server from a VB program running on a client. Can you point me in the right direction?

Answer:
None of the NT Unicode network functions are particularly easy to use. In fact, they are a real pain. However, the following code will do what you want:

' ************************************************' In a form' ************************************************Option ExplicitPrivate Sub Command1_Click()On Error Resume Next   Dim p_vntRtn   As Variant   Dim p_lngNum   As Long   Dim p_lngLoop  As Long   Dim p_strGroup As String      p_strGroup = Trim$(Me.List1.List(Me.List1.ListIndex))   If Len(p_strGroup)  0 Then      For p_lngLoop = 1 To p_lngNum         Me.List2.AddItem p_vntRtn(p_lngLoop)      Next p_lngLoop   End If   End SubPrivate Sub Command2_Click()On Error Resume Next   Dim p_vntRtn   As Variant   Dim p_lngNum   As Long   Dim p_lngLoop  As Long      Me.List1.Clear   p_vntRtn = GetLocalGroups("")      p_lngNum = UBound(p_vntRtn)   If p_lngNum > 0 Then      For p_lngLoop = 1 To p_lngNum         Me.List1.AddItem p_vntRtn(p_lngLoop)      Next p_lngLoop   End If   End SubPrivate Sub Command3_Click()   Dim p_blnRtn   As Boolean   Dim p_strGroup As String   Dim p_strUser  As String      p_strGroup = Trim$(Me.List1.List(Me.List1.ListIndex))   If Len(p_strGroup)  0 Then         For p_lngLoop = 0 To p_lngEntriesRead - 1            p_strSidType = TranslateSidUsage(p_alngMemberInfo((p_lngLoop * 3) + 1))            p_strUserName = PointerToStringW(p_alngMemberInfo((p_lngLoop * 3) + 2))            p_astrMemberInfo(p_lngLoop + 1) = p_strUserName & " [" & p_strSidType & "]"         Next p_lngLoop      End If            If p_lngPtrBuffer Then         NetApiBufferFree p_lngPtrBuffer      End If            GetLocalGroupMembers = p_astrMemberInfo   Else      GetLocalGroupMembers = ""   End If   End Function' ================================================' Get all of the local groups' ================================================Public Function GetLocalGroups(ByVal xi_strServerName As String) As Variant   Dim p_lngRtn                     As Long   Dim p_lngLoop                    As Long   Dim p_lngPtrBuffer               As Long   Dim p_lngPtrServerName           As Long   Dim p_lngPreferredMaxLen         As Long   Dim p_lngResumeHwnd              As Long   Dim p_lngEntriesRead             As Long   Dim p_lngTotalEntries            As Long   Dim p_alngGroupInfo()            As Long   Dim p_astrGroupInfo()            As String      ' Convert the server name to a pointer   If Len(Trim$(xi_strServerName)) = 0 Then      p_lngPtrServerName = 0&   Else      p_lngPtrServerName = StrPtr(xi_strServerName)   End If   p_lngPreferredMaxLen = 4096&   p_lngResumeHwnd = 0&   p_lngRtn = NetLocalGroupEnum(p_lngPtrServerName, _                                LocalGroupInfo0, _                                p_lngPtrBuffer, _                                p_lngPreferredMaxLen, _                                p_lngEntriesRead, _                                p_lngTotalEntries, _                                p_lngResumeHwnd)   If p_lngRtn = NERR_Success Then      ReDim p_alngGroupInfo(0 To p_lngEntriesRead - 1) As Long      ReDim p_astrGroupInfo(1 To p_lngEntriesRead) As String            ' This gets the pointers to the structures      CopyMem p_alngGroupInfo(0), _              ByVal p_lngPtrBuffer, _              p_lngEntriesRead * 4            If p_lngEntriesRead > 0 Then         For p_lngLoop = 0 To p_lngEntriesRead - 1            p_astrGroupInfo(p_lngLoop + 1) = PointerToStringW(p_alngGroupInfo(p_lngLoop))         Next p_lngLoop      End If            If p_lngPtrBuffer Then         NetApiBufferFree p_lngPtrBuffer      End If            GetLocalGroups = p_astrGroupInfo   Else      GetLocalGroups = ""   End If   End Function' ================================================' Either add or delete a user from a selected' local group (depends upon xi_blnAddUser)' ================================================Function AddDelUserToLocal(ByVal xi_strGroupName As String, _                           ByVal xi_strUserName As String, _                           ByVal xi_strServerName As String, _                           ByVal xi_blnAddUser As Boolean) As Boolean   Dim p_lngPtrGroupName   As Long   Dim p_lngPtrUserName    As Long   Dim p_lngPtrServerName  As Long   Dim p_lngMemberCount    As Long   Dim p_lngRtn            As Long      ' Convert the server name to a pointer   If Len(Trim$(xi_strServerName)) = 0 Then      p_lngPtrServerName = 0&   Else      p_lngPtrServerName = StrPtr(xi_strServerName)   End If   ' Convert the group name to a pointer   p_lngPtrGroupName = StrPtr(xi_strGroupName)      ' Convert the user name to a pointer   p_lngPtrUserName = StrPtr(xi_strUserName)      ' Add the user   p_lngMemberCount = 1      If xi_blnAddUser = True Then      p_lngRtn = NetLocalGroupAddMembers(p_lngPtrServerName, _                                         p_lngPtrGroupName, _                                         LocalGroupMembersInfo3, _                                         p_lngPtrUserName, _                                         p_lngMemberCount)   Else      p_lngRtn = NetLocalGroupDelMembers(p_lngPtrServerName, _                                         p_lngPtrGroupName, _                                         LocalGroupMembersInfo3, _                                         p_lngPtrUserName, _                                         p_lngMemberCount)   End If      If p_lngRtn = NERR_Success Then      AddDelUserToLocal = True   Else      AddDelUserToLocal = False   End If   End Function' ================================================' Convert the SID type to a text string' ================================================Private Function TranslateSidUsage(ByVal xi_lngSidType As Long) As String   Dim p_strTmp                  As String      Select Case xi_lngSidType      Case SidTypeUser         p_strTmp = "User Account"      Case SidTypeGroup         p_strTmp = "Global Group Account"      Case SidTypeDomain         p_strTmp = "Domain Group Account"      Case SidTypeAlias         p_strTmp = "Alias Account"      Case SidTypeWellKnownGroup         p_strTmp = "Well-known Group Account (ie, Everyone)"      Case SidTypeDeletedAccount         p_strTmp = "Deleted Account"      Case SidTypeInvalid         p_strTmp = "Invalid Account"      Case SidTypeUnknown         p_strTmp = "Account Type Cannot Be Determined"      Case Else         p_strTmp = "Bad Parameter for Sid Usage"   End Select      ' Set the return value   TranslateSidUsage = p_strTmp   End Function' ================================================' Convert a pointer to a string into a string' ================================================Public Function PointerToStringW(ByVal xi_lngPtrToString As Long) As String   Dim p_strText           As String   Dim p_lngLength         As Long   If xi_lngPtrToString Then         p_lngLength = lstrlenW(xi_lngPtrToString)      If p_lngLength > 0 Then         p_strText = Space$(p_lngLength)         CopyMem ByVal StrPtr(p_strText), ByVal xi_lngPtrToString, p_lngLength * 2      End If   End If      PointerToStringW = p_strTextEnd Function' ================================================' Convert a pointer to a string into a string via ' a byte array' ================================================Private Function PointerToStringWByte(ByVal xi_lngPtrToString As Long) As String   Dim p_abytBuffer()      As Byte   Dim p_lngLen            As Long      If xi_lngPtrToString  0 Then      p_lngLen = lstrlenW(xi_lngPtrToString) * 2      If p_lngLen Then         ReDim p_abytBuffer(0 To (p_lngLen - 1)) As Byte         CopyMem p_abytBuffer(0), ByVal xi_lngPtrToString, p_lngLen         PointerToStringWByte = p_abytBuffer      End If   End If   End Function

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist