This has to be obtained from a remote machine. The following query works not for SIDs, but for group and account names.
"SELECT GroupComponent FROM Win32_GroupUser WHERE PartComponent = \"Win32_UserAccount.Domain='" + accountDomain + "',Name='" + accountName + "'\""
The Win32_Group objects it returns come in the forms of strings, and they only have domain and name (even though Win32_Group has a SID property).
I have this sinking feeling I'll have to:
- Turn the SID into an account name by querying Win32_SID;
- Perform the query above;
- Turn each of the resulting group names into SIDs by querying Win32_Group.
Yes there is but some methods depend on having a domain.
See this page for how to convert a SID to a user id using P/Invoke and the Windows API, or with .NET 2.0+ and no P/Invoke.
using System.Security.Principal;
// convert the user sid to a domain\name string account = new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString();
If you have AD and the user id in there then use the DirectorySearcher method or Account Management APIs to find the groups. Otherwise use the method outlined in this article to get local groups.
In an ASP.NET application it is possible to use code like this to access group info provided a user is authenticated by Windows and not Forms authentication. In this example I've left an interesting note about exceptions that are thrown in that environment but it may apply to other users:
LogonUserIdentity is based on the WindowsIdentity class. You could modify my code sample to use WindowsIdentity and function in a non-Web application. Once you iterate over a group you should be able to do something like this to get the SecurityIdentifier:
Can you use the System.DirectoryServices.AccountManagement namespace classes?
It should work with ContextType.Machine, though you'd need to specify the machine name and have appropriate privileges.
There's a nice MSDN article (longish, though) on using the new .NET 3.5 account management namespace.