Friday, July 06, 2012

Finding all machines a user owns in Active Directory

Here's a quick and dirty way to find all machines a user owns in Active Directory. Performance is not good though, as the objects are processed client side. I was not able to find any way of doing server side queries dealing with the ntSecurityDescriptor field. Please let me know if you find a way!

Adjust the DN strings as needed.

using System;
using System.DirectoryServices;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime startTime = DateTime.Now;

            DirectoryEntry d = new DirectoryEntry("LDAP://ou=UserAccounts,dc=contoso,dc=com");
            DirectorySearcher s = new DirectorySearcher(d, "(&(objectClass=user)(cn=John Smith))",
                new string[] { "cn", "objectsid" });

            string sid = BitConverter.ToString(
                    (byte[])s.FindOne().Properties["objectsid"][0])
                .Replace("-", "");

            int count = 0;
            d = new DirectoryEntry("LDAP://ou=Machines,dc=contoso,dc=com");
            s = new DirectorySearcher(d, "(&(objectCategory=computer)(objectClass=computer)(cn=*))",
                new string[] { "cn", "ntSecurityDescriptor" });
            s.PageSize = 500;
            s.SecurityMasks = SecurityMasks.Owner;
            foreach (SearchResult r in s.FindAll())
            {
                count++;
                string cn = (string)r.Properties["cn"][0];
                string sd = BitConverter.ToString((byte[])r.Properties["ntsecuritydescriptor"][0]).Replace("-", "");

                if (sd.Contains(sid))
                    Console.WriteLine(cn);
            }

            Console.WriteLine();
            Console.WriteLine("Checked " + count + " objects");
            Console.WriteLine("Query finished in " + (DateTime.Now - startTime));
        }
    }
}

No comments:

Post a Comment