Tag Archives: Active directory

List AD users in a group using powershell

This is not a rocket science thing since there are apparently multiple ways to do this but I had a specific requirement to quickly get a list of users for a group but only list specific properties which include the “Title” property that is not available using the AccountManagement namespace.

So without mush further ado… here is a simple script that works for me.

# Read the input parameters $GroupName
param([string] $GroupName = $(throw write-host "Please specify the group name." -Foregroundcolor Red))

$Recurse = $true

$OutputFile = "GroupUsers.csv"
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$group=[System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($ct, $GroupName)
$members = $group.GetMembers($Recurse)

$columnNames = "Name,Title,Description"
$columnNames | Out-File -FilePath $OutputFile -Encoding 'UTF8'
foreach($user in $members){
    $DE = $user.GetUnderlyingObject()
    $output = $user.name + "," + $DE.title + "," + $user.description

    Write-Host $output
    $output | Out-File -FilePath $OutputFile -Encoding 'UTF8' -append
    $output = ""
}

In order to get to the ‘Title’ property I use the ‘GetUnderlyingObject’ method to get the DirectoryEntry object which do have the ‘Title’ property. This way it makes it possible to access any/all the ‘forgotten’ properties which they never implemented in the new namespace.
Additionally it also save the output to a CSV file.

Getting list of disabled users in AD

Having to quickly help some colleagues find a list of all the currently disabled users on a domain I created a quick Powershell script (with some help from Google of course).

I suspect other people might also like to know how to do it so here is a copy of the script.

This script is easily modifiable to search for all kind of other ‘stuff’ in AD as well.

DirectorySearcher and filters to search AD

If you want to do a query against AD (active directory) there are several ways to do it – but (only) one proper way like usual.

The DirectorySearcher class has a ‘filter’ property that allows you to filter the returned results – oppose to you having to test each property in code. The syntax of this filter is a bit tricky (ok a lot…)

It took me a while to figure out how to properly set up a filter to do more complex queries – like when you have multiple things to filter by including ‘and’s and ‘or’s. Anyway, I found a good reference here: Search Filter Syntax.

It explains the syntax plus give some examples. It also list some special characters plus explain how to use ‘wildcards’.

Happy searching…

Check if user is in AD group

This is an action that often is required when you want to make sure a user account may access some resource only if they are part of some AD (OU) group. There are other ways to do this – if fact it is a lot easier if you use newer versions on the .Net framework (like 3.5 and later) but I had to create something that will still work with the 2.0 framework – thanks to some older 2003 servers that I have to manage.

I’m not going to explain too much details on how it works internally – the simple explanation is that I take the user account and loop through the list of groups the user is a ‘memberOf’. One tricky thing is to also cater for cross domain accounts/groups – like when you have a dev domain that also have groups but the user account is part of the live domain – or some combination like it.

A solution

The solution is a single helper class with one public method – IsUserInGroup(string userName, string groupName). Creating an instance of a class with one method is a bit of a waste so the class is a simple static class.

public static class DirectoryServicesHelper
{

private static bool useDomainName = false;

public static bool IsUserInGroup(string userName, string groupName)
{

useDomainName = userName.Contains(“\\”) || groupName.Contains(“\\”);
List<string> userGroups = GetGroupsForUser(userName);
if (userGroups.Contains(groupName.ToLower()))

return true;

return false;

}

The ‘useDomainName’ variable is there simply to indicate to other methods if they must cater for domain level details or not. Most of the rest of the code is inside the private ‘GetGroupsForUser’ method.

private static List<string> GetGroupsForUser(string pstrUser)
{

List<string> lstGroups = new List<string>();

string domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain().Name;
DirectoryEntry rootEntry;
if (useDomainName && pstrUser.Contains(“\\”))
{

domain = pstrUser.Substring(0, pstrUser.IndexOf(“\\”));
pstrUser = pstrUser.Substring(pstrUser.IndexOf(“\\”) + 1);

}
rootEntry = new DirectoryEntry(“LDAP://” + domain);

using (DirectorySearcher searcher = new DirectorySearcher(rootEntry, “objectCategory=User”))
{

searcher.Filter = string.Format(“(SAMAccountName={0})”, pstrUser);
SearchResult objSR = searcher.FindOne();
if (objSR != null)
{

using (DirectoryEntry objUser = new DirectoryEntry(objSR.Path))
{

System.DirectoryServices.PropertyCollection colProperties = objUser.Properties;
PropertyValueCollection colPropertyValues = colProperties[“memberOf”];
foreach (string strGroup in colPropertyValues)
{

lstGroups.Add(GetSAMAccountName(strGroup).ToLower());

}

}

}

}
return lstGroups;

}

private static string GetDomainNameFromDE(DirectoryEntry entry)
{

if (entry == null)

return “”;

else
{

if (entry.SchemaClassName == “domainDNS”)

return entry.Properties[“Name”].Value.ToString();

else if (entry.Parent != null)

return GetDomainNameFromDE(entry.Parent);

else

return “”;

}

}

private static string GetSAMAccountName(string pstrPath)
{

DirectoryEntry objADEntry = null;
string output = “”;
objADEntry = new DirectoryEntry(“LDAP://” + pstrPath);
if (objADEntry != null)
{

if (useDomainName)

output = GetDomainNameFromDE(objADEntry) + “\\” + objADEntry.Properties[“SAMAccountName”].Value.ToString();

else

output = objADEntry.Properties[“SAMAccountName”].Value.ToString();

}
return output;

}

Summary

I’ve excluded any error checking to make the code simpler to read. For a real utility class you need to add it since AD is an unmanaged resource (as far as .Net goes) and it can throw COM+ errors as well.

With this little helper class you can simply pass it a user and group name and it will return a true or false if the user is part of the group. I’ve tested it with no domain details, partial domain details, mixed domains etc. Hopefully it can help someone else as well.