Click here to Skip to main content
Licence 
First Posted 24 Sep 2002
Views 97,085
Bookmarked 25 times

Getting local groups and member names in C#

By | 24 Sep 2002 | Article
How to get local groups and members with Win32 API in C#

Introduction

Some days before, I read the C# Server Enumerator article by Phil Bolduc. He used some API to get server names. After that I decided to use his style and use some other functions like NetLocalGroupEnum and NetLocalGroupGetMembers. These functions as their name shows look into the local computer and get group names and group members. If you want to get these names in your network you can use NetGroupEnum and NetGroupGetUsers. These two function are defined exactly the same as the first two.

Code Listing

First I define an internal class and name it Win32API. Then I import functions and structures there.

internal class Win32API
{
#region Win32 API Interfaces
    [DllImport( "netapi32.dll", EntryPoint = "NetApiBufferFree" )]
    internal static extern void NetApiBufferFree(IntPtr bufptr);

    [DllImport( "netapi32.dll", EntryPoint = "NetLocalGroupGetMembers" )]
    internal static extern uint NetLocalGroupGetMembers(
        IntPtr ServerName,
        IntPtr GrouprName,
        uint level,
        ref IntPtr siPtr,
        uint prefmaxlen,
        ref uint entriesread,
        ref uint totalentries,
        IntPtr resumeHandle);

    [DllImport( "netapi32.dll", EntryPoint = "NetLocalGroupEnum" )]
    internal static extern uint NetLocalGroupEnum(
        IntPtr ServerName, 
        uint level,
        ref IntPtr siPtr,
        uint prefmaxlen,
        ref uint entriesread,
        ref uint totalentries,
        IntPtr resumeHandle);

    [StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Auto)]
    internal struct LOCALGROUP_MEMBERS_INFO_1
    { 
        public IntPtr lgrmi1_sid;
        public IntPtr lgrmi1_sidusage;
        public IntPtr lgrmi1_name;

    }

    [StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Auto)]
    internal struct LOCALGROUP_INFO_1 
    { 
        public IntPtr lpszGroupName;
        public IntPtr lpszComment;
    }
#endregion
}

LOCALGROUP_MEMBER_INFO_1 and LOCALGROUP+INFO_1 are two structures that receive information about groups and members. Like their names, comments, SIDs.

Using these functions is made very clear in the demo project. There is a button in my form and when you click it, it gets group and member names and shows each group in a tree view and shows their members in sub-nodes. I also added some comments to make everything clear.

private void groupbtn_Click(object sender, System.EventArgs e)
{
    //defining values for getting group names
    uint level = 1, prefmaxlen = 0xFFFFFFFF, 
        entriesread = 0, totalentries = 0;

    //Values that will receive information.
    IntPtr GroupInfoPtr,UserInfoPtr;
    GroupInfoPtr = IntPtr.Zero;
    UserInfoPtr = IntPtr.Zero;

    Win32API.NetLocalGroupEnum(
        IntPtr.Zero, //Server name.it must be null
        level,//level can be 0 or 1 for groups.
            //For more information see LOCALGROUP_INFO_0 
            //and LOCALGROUP_INFO_1
        ref GroupInfoPtr,//Value that will be receive information
        prefmaxlen,//maximum length
        ref entriesread,//value that receives the count of 
            //elements actually enumerated. 
        ref totalentries,//value that receives the approximate total 
            //number of entries that could have been 
            //enumerated from the current resume position.
        IntPtr.Zero);

    //this string array will hold comments of each group
    commentArray = new string[totalentries];

    grouptv.Nodes.Clear();
    label1.Visible = true;

    //getting group names and add them to tree view
    for(int i = 0;i< totalentries ;i++)
    {
        //converting unmanaged code to managed codes 
        //with using Marshal class 
        int newOffset = GroupInfoPtr.ToInt32() + 
            LOCALGROUP_INFO_1_SIZE * i;
        Win32API.LOCALGROUP_INFO_1 groupInfo = 
            (Win32API.LOCALGROUP_INFO_1)Marshal.PtrToStructure(
                new IntPtr(newOffset), 
            typeof(Win32API.LOCALGROUP_INFO_1));
        string currentGroupName = 
            Marshal.PtrToStringAuto(groupInfo.lpszGroupName);

        //storing group comment in an string array to 
        //show it in a label later
        commentArray[i] = Marshal.PtrToStringAuto(groupInfo.lpszComment);
        //add group name to tree
        grouptv.Nodes.Add(currentGroupName);

        //defining value for getting name of members in each group
        uint prefmaxlen1 = 0xFFFFFFFF, entriesread1 = 0, 
            totalentries1 = 0;

        //paramaeters for NetLocalGroupGetMembers is 
        //like NetLocalGroupEnum.
        Win32API.NetLocalGroupGetMembers(IntPtr.Zero,
            groupInfo.lpszGroupName,1,
            ref UserInfoPtr,prefmaxlen1,
            ref entriesread1,ref totalentries1,
            IntPtr.Zero);

        //getting members name
        for(int j = 0; j< totalentries1; j++)
        {
            //converting unmanaged code to managed codes with 
            //using Marshal class 
            int newOffset1 = UserInfoPtr.ToInt32() + 
                LOCALGROUP_MEMBERS_INFO_1_SIZE * j;
            Win32API.LOCALGROUP_MEMBERS_INFO_1 memberInfo = 
                (Win32API.LOCALGROUP_MEMBERS_INFO_1)Marshal.PtrToStructure(
                    new IntPtr(newOffset1), 
                    typeof(Win32API.LOCALGROUP_MEMBERS_INFO_1));
            string currentUserName = 
                Marshal.PtrToStringAuto(memberInfo.lgrmi1_name);
            //adding member name to tree view
            grouptv.Nodes[i].Nodes.Add(currentUserName);
        }
        //free memory
        Win32API.NetApiBufferFree(UserInfoPtr);
    }
    //free memory
    Win32API.NetApiBufferFree(GroupInfoPtr);
}

Note:

The source code must be compiled with unsafe code enabled.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Mazdak

Web Developer

Iran (Islamic Republic Of) Iran (Islamic Republic Of)

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralDomain name along with account names Pinmembershashankkadge5:23 3 Jun '08  
GeneralRe: Domain name along with account names PinmemberArto1234:08 28 Oct '08  
Questionc# PinmemberSumanta Kumar Das21:08 13 Mar '08  
GeneralNetLocalGroupAddMembers PinmemberMehdi Mokhtari20:00 9 Apr '07  
GeneralRemoving unsafe PinmemberMark Abela12:17 29 Jan '07  
GeneralRe: Removing unsafe PinmemberDries de Groot3:08 1 Sep '08  
Generalgroup in vss Pinmemberadv200523:57 5 Mar '06  
GeneralCould you please write a sample, it can find all workstations in a domain, all groups in one workstation PinmemberJackfan17:06 27 Jan '03  
GeneralRe: Could you please write a sample, it can find all workstations in a domain, all groups in one workstation PinmemberMazdak20:59 31 Jan '03  
QuestionCan you help me ? PinsussAnonymous21:58 12 Nov '02  
AnswerRe: Can you help me ? PinmemberMazdak8:14 13 Nov '02  
GeneralRe: Can you help me ? PinsussAnonymous15:11 13 Nov '02  
GeneralRe: Can you help me ? PinmemberMazdak21:03 13 Nov '02  
GeneralGood one, Mazy PineditorNishant S12:34 26 Sep '02  
GeneralRe: Good one, Mazy PinmemberMazdak3:32 27 Sep '02  
GeneralRe: Good one, Mazy PineditorNishant S13:13 27 Sep '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 25 Sep 2002
Article Copyright 2002 by Mazdak
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid