<p>I wondered whether anybody knows how to obtain membership of local groups on a remote server programmatically via C#. Would this require administrator permissions? And if so is there any way to confirm the currently logged in user's membership (or not) of these groups?</p>

[{'answer_id': 45439, 'author': 'Patrik Svensson', 'author_id': 936, 'author_profile': 'https://Stackoverflow.com/users/936', 'pm_score': 0, 'selected': False, 'text': '<p>Perhaps this is something that can be done via WMI?</p>\n'}, {'answer_id': 45458, 'author': 'Espo', 'author_id': 2257, 'author_profile': 'https://Stackoverflow.com/users/2257', 'pm_score': 2, 'selected': False, 'text': '<p><a href="http://www.codeproject.com/KB/system/everythingInAD.aspx" rel="nofollow noreferrer">Howto: (Almost) Everything In Active Directory via C#</a> is very helpfull and also includes instructions on how to iterate AD members in a group.</p>\n\n<pre><code>public ArrayList Groups(string userDn, bool recursive)\n{\n    ArrayList groupMemberships = new ArrayList();\n    return AttributeValuesMultiString("memberOf", userDn,\n        groupMemberships, recursive);\n}\n</code></pre>\n\n<p>You will also need this function:</p>\n\n<pre><code>public ArrayList AttributeValuesMultiString(string attributeName,\n     string objectDn, ArrayList valuesCollection, bool recursive)\n{\n    DirectoryEntry ent = new DirectoryEntry(objectDn);\n    PropertyValueCollection ValueCollection = ent.Properties[attributeName];\n    IEnumerator en = ValueCollection.GetEnumerator();\n\n    while (en.MoveNext())\n    {\n        if (en.Current != null)\n        {\n            if (!valuesCollection.Contains(en.Current.ToString()))\n            {\n                valuesCollection.Add(en.Current.ToString());\n                if (recursive)\n                {\n                    AttributeValuesMultiString(attributeName, "LDAP://" +\n                    en.Current.ToString(), valuesCollection, true);\n                }\n            }\n        }\n    }\n    ent.Close();\n    ent.Dispose();\n    return valuesCollection;\n}\n</code></pre>\n\n<p>If you do now want to use this AD-method, you could use the info in this article, but it uses unmanaged code:</p>\n\n<p><a href="http://www.codeproject.com/KB/cs/groupandmembers.aspx" rel="nofollow noreferrer">http://www.codeproject.com/KB/cs/groupandmembers.aspx</a></p>\n\n<p>The sample application that they made:</p>\n\n<p><img src="https://i.stack.imgur.com/9Vt9Z.jpg" alt="alt text"></p>\n'}, {'answer_id': 45521, 'author': 'ljs', 'author_id': 3394, 'author_profile': 'https://Stackoverflow.com/users/3394', 'pm_score': 2, 'selected': False, 'text': '<p>It appears there is a new Assembly in .net 3.5 called System.DirectoryServices.AccountManagement which gives a cleaner implementation than System.DirectoryServices. <a href="http://www.leastprivilege.com/SystemDirectoryServicesAccountManagement.aspx" rel="nofollow noreferrer">Dominick Baier blogs about</a> a couple of simple operations including checking membership of a group:-</p>\n\n<pre><code>public static bool IsUserInGroup(string username, string groupname, ContextType type)\n{\n    PrincipalContext context = new PrincipalContext(type);\n\n    UserPrincipal user = UserPrincipal.FindByIdentity(\n        context,\n        IdentityType.SamAccountName,\n        username);\n    GroupPrincipal group = GroupPrincipal.FindByIdentity(\n        context, groupname);\n\n    return user.IsMemberOf(group);\n}\n</code></pre>\n\n<p>I think I will use this approach, thanks for the suggestions though however! :-)</p>\n'}, {'answer_id': 48465, 'author': 'quux', 'author_id': 2383, 'author_profile': 'https://Stackoverflow.com/users/2383', 'pm_score': 0, 'selected': False, 'text': '<p>I asked a similar question, and ended up writing an <a href="https://stackoverflow.com/questions/21514/enumerate-windows-user-group-members-on-remote-system-using-c#24075">answer</a> which used WMI to enum the group members. I had real problems with authentication in the system.directoryservices.accountmanagement stuff. YMMV, of course.</p>\n'}, {'answer_id': 48469, 'author': 'fuzzbone', 'author_id': 5027, 'author_profile': 'https://Stackoverflow.com/users/5027', 'pm_score': 0, 'selected': False, 'text': "<p>I'd be curious if the System.DirectoryServices.AccountManagement is fully managed.  I've used System.DirectoryServices.ActiveDirectory which is a wrapper for COM Interop which has led to many headaches...</p>\n"}, {'answer_id': 323056, 'author': 'Jon DellOro', 'author_id': 36456, 'author_profile': 'https://Stackoverflow.com/users/36456', 'pm_score': 0, 'selected': False, 'text': '<p>This may possibly help.  I had to develop an app where we want to authenticate against active directory, and also examine the groups strings that the user is in.</p>\n\n<p>For a couple of reasons we don\'t want to use windows authentication, but rather have our own forms based authentication.  I developed the routine below to firstly authenticate the user, and secondly examine all the groups that the user belongs to.  Perhaps it may help.  The routine uses LogonUser to authenticate, and then gets the list of numerical guid-like group ids (SIDs) for that user, and translates each one to a human readable form.</p>\n\n<p>Hope this helps, I had to synthesise this approach from a variety of different google searches.</p>\n\n<pre><code>private int validateUserActiveDirectory()\n{\n    IntPtr token = IntPtr.Zero;\n    int DBgroupLevel = 0;\n\n    // make sure you\'re yourself -- recommended at msdn http://support.microsoft.com/kb/248187\n    RevertToSelf();\n\n    if (LogonUser(txtUserName.Value, propDomain, txtUserPass.Text, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, token) != 0) {\n        // ImpersonateLoggedOnUser not required for us -- we are not doing impersonated stuff, but leave it here for completeness.\n        //ImpersonateLoggedOnUser(token);\n        // do impersonated stuff\n        // end impersonated stuff\n\n        // ensure that we are the original user\n        CloseHandle(token);\n        RevertToSelf();\n\n        System.Security.Principal.IdentityReferenceCollection groups = Context.Request.LogonUserIdentity.Groups;\n        IdentityReference translatedGroup = default(IdentityReference);\n\n        foreach (IdentityReference g in groups) {\n            translatedGroup = g.Translate(typeof(NTAccount));\n            if (translatedGroup.Value.ToLower().Contains("desired group")) {\n                inDBGroup = true;\n                return 1;\n            }\n        }\n    }\n    else {\n        return 0;\n    }\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/45437', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3394/']