List Windows users and groups in C#

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.

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);
    } 
}
Last updated on 04 April 2009

Comments

blog comments powered by Disqus