davidg was on the right track, and I am crediting him with the answer.
But the WMI query necessary was a little less than straightfoward, since I needed not just a list of users for the whole machine, but the subset of users and groups, whether local or domain, that were members of the local Administrators group. For the record, that WMI query was:
SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent = "Win32_Group.Domain='thehostname',Name='thegroupname'"
Here's the full code snippet:
public string GroupMembers(string targethost, string groupname, string targetusername, string targetpassword)
{
StringBuilder result = new StringBuilder();
try
{
ConnectionOptions Conn = new ConnectionOptions();
if (targethost != Environment.MachineName) //WMI errors if creds given for localhost
{
Conn.Username = targetusername; //can be null
Conn.Password = targetpassword; //can be null
}
Conn.Timeout = TimeSpan.FromSeconds(2);
ManagementScope scope = new ManagementScope("\\\\" + targethost + "\\root\\cimv2", Conn);
scope.Connect();
StringBuilder qs = new StringBuilder();
qs.Append("SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent = \"Win32_Group.Domain='");
qs.Append(targethost);
qs.Append("',Name='");
qs.Append(groupname);
qs.AppendLine("'\"");
ObjectQuery query = new ObjectQuery(qs.ToString());
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
ManagementPath path = new ManagementPath(m["PartComponent"].ToString());
{
String[] names = path.RelativePath.Split(',');
result.Append(names[0].Substring(names[0].IndexOf("=") + 1).Replace("\"", " ").Trim() + "\\");
result.AppendLine(names[1].Substring(names[1].IndexOf("=") + 1).Replace("\"", " ").Trim());
}
}
return result.ToString();
}
catch (Exception e)
{
Console.WriteLine("Error. Message: " + e.Message);
return "fail";
}
}
So, if I invoke Groupmembers("Server1", "Administrators", "myusername", "mypassword"); I get a single string returned with:
SERVER1\Administrator
MYDOMAIN\Domain Admins
The actual WMI return is more like this:
\\SERVER1\root\cimv2:Win32_UserAccount.Domain="SERVER1",Name="Administrator"
... so as you can see, I had to do a little string manipulation to pretty it up.