Count AD disabled accounts C#

Greetings,
I'm using system.directoryservices.accountmanagment and c# I'm trying to programmatically count the number of disabled accounts on the network.

Here is the part of the code that I'm using to get that those numbers.
int count = 0;
UserPrincipal u  = new UserPrincipal(ctx);
PrincipalSearcher s = new PrincipalSearcher();
s.QueryFilter = u;
foreach(Principal p in u.FindAll())
{
if(u.Enabled == false)
count++;
}

// then I gon on to display count

Problem is that it always displays 0. Please help. Thanks. I eventually want to be able to programmatically find the number of lockedaccounts as well.
 
centemAsked:
Who is Participating?
 
Russell_VenableConnect With a Mentor Commented:
I do believe I overlooked that part. I did a quick rewrite of it using VS2010 Pro.
using System;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace DisabledADAccounts
{
    class Program
    {
        static void Main(string[] args)
        {

            int count = 0;
            // Set search context.
            PrincipalContext ctx = new PrincipalContext(
                                      ContextType.ApplicationDirectory,
                                      "Host.Server.com:5000",
                                      "DC=SomeApp,DC=Server,DC=com",
                                      "Admin", "SecretPwd123");
            // Set filter to search for disabled accounts.
            UserPrincipal user = new UserPrincipal(ctx);
            // Check for disabled accounts set.
            user.Enabled = false;
            // Set name to search for. No error checking added here.
            user.Name = args[0]; // "user*"
            // Query for specific user. Asterisks are allowed.
            PrincipalSearcher s = new PrincipalSearcher(user);
            s.QueryFilter = user;
            PrincipalSearchResult<Principal> results = s.FindAll();
            Console.WriteLine("Disabled accounts starting with a name of [{0}]:", user.Name);

            // Go through PrincipleSearchResult array and store in principle variable for display.
            foreach (Principal result in results)
            {
                // Display disabled account name.
                Console.WriteLine("name: {0}", result.Name);
                count++;
            }
            Console.WriteLine("[*] # of Accounts Disabled searching for [{0}]: {1}", user.Name, count);
        }
    }
}

Open in new window



The problem with your code was it was returning the boolean number as result. If you put false it puts 1 if you put true it gives a 0. So having said that it will always give that number. Also the foreach loop was useless given that you did not utilize the stored variable (Principle) "p" instead you used (UserPrincipal) "u" which ignores the loop completely.  That is what I meant. The above code should work just like you want it too.

0
 
Netman66Commented:
Did you try u.Disabled == True?
0
 
centemAuthor Commented:
Yes. I did. The only time I dont get a count of 0 is when I remove the if statement. In which case its just counting the number of users in AD.
0
Free tool for managing users' photos in Office 365

Easily upload multiple users’ photos to Office 365. Manage them with an intuitive GUI and use handy built-in cropping and resizing options. Link photos with users based on Azure AD attributes. Free tool!

 
Russell_VenableCommented:
As I am not seeing a specific server version for this question along with details I will suggest that you take a look at this answer from stackoverflow by Leandro López. It uses LDAP over AD to find disabled accounts.


class Program
{
    static void Main(string[] args)
    {
        const string ldap = "LDAP://your-ldap-server-here";

        using (DirectoryEntry conn = new DirectoryEntry(ldap))
        {
            using (DirectorySearcher searcher = new DirectorySearcher(conn))
            {
                searcher.Filter = "(|(samAccountName=userA)(samAccountName=userB))";
                searcher.PropertiesToLoad.Add("samAccountName");
                searcher.PropertiesToLoad.Add("userAccountControl");

                using (SearchResultCollection results = searcher.FindAll())
                {
                    foreach (SearchResult result in results)
                    {
                        int userAccountControl = Convert.ToInt32(result.Properties["userAccountControl"][0]);
                        string samAccountName = Convert.ToString(result.Properties["samAccountName"][0]);
                        bool disabled = ((userAccountControl & 2) > 0);

                        Console.WriteLine("{0} ({1:x}) :: {2}", samAccountName, userAccountControl, disabled);
                    }
                }
            }
        }

        Console.ReadLine();
    }
}

Open in new window

Leandro López:The second bit of userAccountControl will be 1 if the account is disabled.

All that really needs to be done is add a count variable and add to it for ever variable found in the foreach loop.

Besides, In your code above. Why would you be using a foreach to loop through a principle and not use the principle already defined to store the variable for each iteration of the loop and then display that instead??? That would explain why you get a 0 everytime as you would be referencing a non changing variable unlike the principle 'p' that is defined to hold the interated values for the loop. hope that helps.

UserPrincipal u  = new UserPrincipal(ctx);
PrincipalSearcher s = new PrincipalSearcher();
s.QueryFilter = u;
foreach(Principal p in u.FindAll())
{
  if(p.Enabled == false)// p instead of u
  count++;
}

Open in new window


0
 
Russell_VenableCommented:
Also taking notes from Joe Kaplan.

You can also add

UserPrincipal u  = new UserPrincipal(ctx);
PrincipalSearcher s = new PrincipalSearcher(u);
s.QueryFilter = u;
PrincipalSearchResult<Principal> results = s.FindAll();
    if (results != null && results.Count() > 0)
    {
        foreach(Principal p in results)
        {
            if(p.Enabled == false)// p instead of u
               count++;
        }
    }
0
 
Russell_VenableCommented:
Thinking about that again you might want to replace s.FindAll() with FindOne() as your setting the Filter Object for one person. I would just make a array filled with a seperate principle searcher that is filled by FindAll() and make a method with the above code and use it recursive until it reaches the end of the array.
0
 
centemAuthor Commented:
Why p instead of u? Principal class does not have a "Enabled" property.
0
 
centemAuthor Commented:
BTW,
I'm running visual studio express 2010 on server 2003 SP 2.
0
All Courses

From novice to tech pro — start learning today.