Click here to Skip to main content
15,886,689 members
Articles / Programming Languages / C#
Article

Getting local groups and member names in C#

Rate me:
Please Sign up or sign in to vote.
4.58/5 (10 votes)
24 Sep 2002 148.7K   1.8K   29   16
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.

C#
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.

C#
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


Written By
Web Developer
Iran (Islamic Republic of) Iran (Islamic Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralDomain name along with account names Pin
shashankkadge3-Jun-08 5:23
shashankkadge3-Jun-08 5:23 
GeneralRe: Domain name along with account names Pin
Arto12328-Oct-08 4:08
Arto12328-Oct-08 4:08 
Questionc# Pin
Sumanta Kumar Das13-Mar-08 21:08
Sumanta Kumar Das13-Mar-08 21:08 
GeneralNetLocalGroupAddMembers Pin
Mehdi Mokhtari9-Apr-07 20:00
Mehdi Mokhtari9-Apr-07 20:00 
GeneralRemoving unsafe Pin
Mark Abela29-Jan-07 12:17
Mark Abela29-Jan-07 12:17 
GeneralRe: Removing unsafe Pin
3sL1-Sep-08 3:08
3sL1-Sep-08 3:08 
Generalgroup in vss Pin
adv20055-Mar-06 23:57
adv20055-Mar-06 23:57 
GeneralCould you please write a sample, it can find all workstations in a domain, all groups in one workstation Pin
Jackfan27-Jan-03 17:06
Jackfan27-Jan-03 17:06 
GeneralRe: Could you please write a sample, it can find all workstations in a domain, all groups in one workstation Pin
Mazdak31-Jan-03 20:59
Mazdak31-Jan-03 20:59 
QuestionCan you help me ? Pin
Anonymous12-Nov-02 21:58
Anonymous12-Nov-02 21:58 
AnswerRe: Can you help me ? Pin
Mazdak13-Nov-02 8:14
Mazdak13-Nov-02 8:14 
GeneralRe: Can you help me ? Pin
Anonymous13-Nov-02 15:11
Anonymous13-Nov-02 15:11 
GeneralRe: Can you help me ? Pin
Mazdak13-Nov-02 21:03
Mazdak13-Nov-02 21:03 
GeneralGood one, Mazy Pin
Nish Nishant26-Sep-02 12:34
sitebuilderNish Nishant26-Sep-02 12:34 
GeneralRe: Good one, Mazy Pin
Mazdak27-Sep-02 3:32
Mazdak27-Sep-02 3:32 
GeneralRe: Good one, Mazy Pin
Nish Nishant27-Sep-02 13:13
sitebuilderNish Nishant27-Sep-02 13:13 

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

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