Chris's coding blog

Listing Windows users and groups in C#

April 16, 2010

This example is borrowed from a newsgroup post, apologies to whoever should take the credit but I lost the original url. It’s a basic console application that prints out access lists and groups lists using WMI for the windows directory.

If you’d rather use the System.DirectoryServices namespace then there is a good example in the roadkill source.

using System;
using System.Management;
using System.Collections;
class Tester
{
[Flags]
enum Mask : uint
{
FILE_READ_DATA = 0x00000001,
FILE_WRITE_DATA = 0x00000002,
FILE_APPEND_DATA = 0x00000004,
FILE_READ_EA = 0x00000008,
FILE_WRITE_EA = 0x00000010,
FILE_EXECUTE = 0x00000020,
FILE_DELETE_CHILD = 0x00000040,
FILE_READ_ATTRIBUTES = 0x00000080,
FILE_WRITE_ATTRIBUTES = 0x00000100,
DELETE = 0x00010000,
READ_CONTROL = 0x00020000,
WRITE_DAC = 0x00040000,
WRITE_OWNER = 0x00080000,
SYNCHRONIZE = 0x00100000,
ACCESS_SYSTEM_SECURITY = 0x01000000,
MAXIMUM_ALLOWED = 0x02000000,
GENERIC_ALL = 0x10000000,
GENERIC_EXECUTE = 0x20000000,
GENERIC_WRITE = 0x40000000,
GENERIC_READ = 0x80000000
}
public static void Main()
{
try
{
ManagementObject lfs = new ManagementObject(@"Win32_LogicalFileSecuritySetting.Path='c:\\windows'");
// Dump all trustees (this includes owner)
foreach (ManagementBaseObject b in lfs.GetRelated())
Console.WriteLine("Trustees {0} is {1}", b["AccountName"], b["SID"]);
// Get the security descriptor for this object
ManagementBaseObject outP = lfs.InvokeMethod("GetSecurityDescriptor", null, null);
if (((uint)(outP.Properties["ReturnValue"].Value)) == 0)
{
ManagementBaseObject Descriptor = ((ManagementBaseObject)(outP.Properties["Descriptor"].Value));
DumpDescriptor(Descriptor);
ManagementBaseObject[] DaclObject = ((ManagementBaseObject[])(Descriptor.Properties["Dacl"].Value));
DumpACEs(DaclObject);
ManagementBaseObject OwnerObject = ((ManagementBaseObject)(Descriptor.Properties["Owner"].Value));
DumpOwnerProperties(OwnerObject.Properties); // Show owner properies
ManagementBaseObject GroupObject = ((ManagementBaseObject)(Descriptor.Properties["Group"].Value));
DumpGroup(GroupObject);
ManagementBaseObject[] SaclObject = ((ManagementBaseObject[])(Descriptor.Properties["SACL"].Value));
DumpSacl(SaclObject);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
}
static void DumpDescriptor(ManagementBaseObject Descriptor)
{
/* Win32_SecurityDescriptor
ControlFlags
DACL
Group
Owner
SACL
*/
Console.WriteLine(Descriptor.ClassPath);
foreach (PropertyData pd in Descriptor.Properties)
Console.WriteLine(pd.Name);
}
static void DumpACEs(ManagementBaseObject[] DaclObject)
{
// ACE masks see: winnt.h
string[] filedesc =
{
"FILE_READ_DATA", "FILE_WRITE_DATA", "FILE_APPEND_DATA", "FILE_READ_EA",
"FILE_WRITE_EA", "FILE_EXECUTE", "FILE_DELETE_CHILD", "FILE_READ_ATTRIBUTES",
"FILE_WRITE_ATTRIBUTES", " ", " ", " ",
" ", " ", " ", " ",
"DELETE ", "READ_CONTROL", "WRITE_DAC", "WRITE_OWNER",
"SYNCHRONIZE ", " ", " "," ",
"ACCESS_SYSTEM_SECURITY", "MAXIMUM_ALLOWED", " "," ",
"GENERIC_ALL", "GENERIC_EXECUTE", "GENERIC_WRITE","GENERIC_READ"
};
foreach (ManagementBaseObject mbo in DaclObject)
{
Console.WriteLine("-------------------------------------------------");
Console.WriteLine("{0:X} - {1} - {2}", mbo["AccessMask"], mbo["AceFlags"], mbo["AceType"]);
// Access allowed/denied ACE
if (mbo["AceType"].ToString() == "1")
Console.WriteLine("DENIED ACE TYPE");
else
Console.WriteLine("ALLOWED ACE TYPE");
// Dump trustees
ManagementBaseObject Trustee = ((ManagementBaseObject)(mbo["Trustee"]));
Console.WriteLine("Name: {0} - Domain: {1} - SID {2}\n",
Trustee.Properties["Name"].Value,
Trustee.Properties["Domain"].Value,
Trustee.Properties["SIDString"].Value);
// Dump ACE mask in readable form
UInt32 mask = (UInt32)mbo["AccessMask"];
// using enum formatting (see emumerating the possibilities.doc)
Console.WriteLine(System.Enum.Format(typeof(Mask), mask, "g"));
}
}
static void DumpGroup(ManagementBaseObject Groups)
{
if (Groups != null)
{
Console.WriteLine("=======================================");
Console.WriteLine("Group property count : " + Groups.Properties.Count);
foreach (PropertyData gd in Groups.Properties)
Console.WriteLine(gd.Name + "\t\t " + gd.Value);
}
else
Console.WriteLine("NO GROUPS Properties ");
}
static void DumpSacl(ManagementBaseObject[] SaclObject)
{
if (SaclObject == null)
Console.WriteLine("No SACLs");
}
static void DumpOwnerProperties(PropertyDataCollection Owner)
{
Console.WriteLine("=============== Owner Properties ========================");
Console.WriteLine();
Console.WriteLine("Domain {0} \tName {1}", Owner["Domain"].Value, Owner["Name"].Value);
Console.WriteLine("SID \t{0}", Owner["SidString"].Value);
}
}
view raw gistfile1.cs hosted with ❤ by GitHub

csharp

I'm Chris Small, a software engineer working in London. This is my tech blog. Find out more about me via GithubStackoverflowResume