I am trying to build a collection of all local groups and their respected members, however the challenge I am having with the listed code bellow is that "Administrators" group members is empty, all other groups on the server returns their members just not administrators. any ideas?
private void BuildGroupMembership(string remoteHost, string targetdomain, string userName, string password, bool domainOnly)
{
var groupsList = new List<string>();
PrincipalContext pContext = null;
PrincipalContext searchContext = null;
if (string.IsNullOrEmpty(remoteHost))
{
remoteHost = Environment.MachineName;
}
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
{
pContext = new PrincipalContext(ContextType.Machine, remoteHost, null, ContextOptions.Negotiate, userName, password);
searchContext = new PrincipalContext(ContextType.Domain, targetdomain, null, ContextOptions.Negotiate, userName, password);
}
else
{
pContext = new PrincipalContext(ContextType.Machine, remoteHost, null, ContextOptions.Negotiate);
searchContext = new PrincipalContext(ContextType.Domain, targetdomain, null, ContextOptions.Negotiate);
}
try
{
var pSearcher = new PrincipalSearcher(new GroupPrincipal(pContext));
foreach (var principal in pSearcher.FindAll().Where(principal => !groupsList.Contains(principal.Name))) groupsList.Add(principal.Name);
foreach (var group in groupsList)
try
{
var groupItem = new Group {GroupName = group};
Groups.Add(groupItem);
var grp = GroupPrincipal.FindByIdentity(pContext, group);
if (grp != null)
{
var allmembers = grp.GetMembers(false).ToList();
var members = domainOnly ? allmembers.Where(x => x.ContextType == ContextType.Domain).ToList() : allmembers.ToList();
foreach (var p in members)
try
{
var adGroup = GroupPrincipal.FindByIdentity(searchContext, IdentityType.Sid, p.Sid.Value);
if (adGroup != null)
{
groupItem.GroupMembers.Add(new GroupMember
{
MemberDomain = adGroup.DistinguishedName.Substring(adGroup.DistinguishedName.IndexOf("DC="), adGroup.DistinguishedName.Length - adGroup.DistinguishedName.IndexOf("DC=")).Replace("DC=", "").Replace(",", "."),
MemberName = p.SamAccountName,
MemberSID = p.Sid.ToString(),
IsGroup = true
});
continue;
}
var adUser = UserPrincipal.FindByIdentity(searchContext, IdentityType.Sid, p.Sid.ToString());
if (adUser != null)
{
groupItem.GroupMembers.Add(new GroupMember
{
MemberDomain = adUser.DistinguishedName.Substring(adUser.DistinguishedName.IndexOf("DC="), adUser.DistinguishedName.Length - adUser.DistinguishedName.IndexOf("DC=")).Replace("DC=", "").Replace(",", "."),
MemberName = p.SamAccountName,
MemberSID = p.Sid.ToString(),
IsGroup = false
});
}
}
catch
{
// ignored
}
grp.Dispose();
}
}
catch
{
}
pContext.Dispose();
searchContext.Dispose();
}
catch (COMException ex)
{
throw new AuthenticationException(ex.Message);
}
}
This doen't answer completely your question but might help you. Using WMI is so much faster than using PrincipalContext, ... (at least in my case). In my app only Administrators and Users where needed.
static Regex partComponentRegex = new Regex("^[^:]+:Win32_UserAccount.Domain=\"(?<Domain>.+?)\",Name=\"(?<Name>.+?)\"$");
static IEnumerable<User> GetUsersFromSidType(WellKnownSidType wellKnownSidType)
{
string gName = GetGroupName(wellKnownSidType);
using (ManagementObjectSearcher groupSearcher = new ManagementObjectSearcher(
string.Format("SELECT * FROM Win32_GroupUser WHERE GroupComponent =\"Win32_Group.Domain='{0}',Name='{1}'\"",
Environment.MachineName,
gName)))
{
foreach (var group in groupSearcher.Get())
{
Match m = partComponentRegex.Match(group["PartComponent"].ToString());
if (m.Success)
{
using (ManagementObjectSearcher userSearcher = new ManagementObjectSearcher(
string.Format("SELECT * FROM Win32_UserAccount WHERE Name='{0}' AND Domain='{1}'",
m.Groups["Name"], m.Groups["Domain"])))
{
foreach (var user in userSearcher.Get())
{
yield return new User()
{
Disabled = (bool)user["Disabled"],
Domain = user["Domain"].ToString(),
FullName = user["FullName"].ToString(),
Name = user["Name"].ToString(),
SID = user["SID"].ToString()
};
}
}
}
}
}
}
static string GetGroupName(WellKnownSidType wellKnownSidType)
{
SecurityIdentifier sid = new SecurityIdentifier(wellKnownSidType, null);
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(
string.Format("SELECT * FROM Win32_Group WHERE SID='{0}'",
sid.Value)))
{
var e = searcher.Get().GetEnumerator();
if (e.MoveNext())
return e.Current["Name"].ToString();
return null;
}
}
Related
I have the following code.
[HttpGet]
public async Task<List<TenantManagementWebApi.Entities.SiteCollection>> Get()
{
var tenant = await TenantHelper.GetActiveTenant();
var siteCollectionStore = CosmosStoreFactory.CreateForEntity<TenantManagementWebApi.Entities.SiteCollection>();
await siteCollectionStore.RemoveAsync(x => x.Title != string.Empty); // Removes all the entities that match the criteria
string domainUrl = tenant.TestSiteCollectionUrl;
string tenantName = domainUrl.Split('.')[0];
string tenantAdminUrl = tenantName + "-admin.sharepoint.com";
KeyVaultHelper keyVaultHelper = new KeyVaultHelper();
await keyVaultHelper.OnGetAsync(tenant.SecretIdentifier);
using (var context = new OfficeDevPnP.Core.AuthenticationManager().GetSharePointOnlineAuthenticatedContextTenant(tenantAdminUrl, tenant.Email, keyVaultHelper.SecretValue))
{
Tenant tenantOnline = new Tenant(context);
SPOSitePropertiesEnumerable siteProps = tenantOnline.GetSitePropertiesFromSharePoint("0", true);
context.Load(siteProps);
context.ExecuteQuery();
List<TenantManagementWebApi.Entities.SiteCollection> sites = new List<TenantManagementWebApi.Entities.SiteCollection>();
foreach (var site in siteProps)
{
if(site.Template.Contains("SITEPAGEPUBLISHING#0") || site.Template.Contains("GROUP#0"))
{
string strTemplate= default(string);
if(site.Template.Contains("SITEPAGEPUBLISHING#0"))
{
strTemplate = "CommunicationSite";
};
if (site.Template.Contains("GROUP#0"))
{
strTemplate = "Modern Team Site";
};
try
{
Guid id = Guid.NewGuid();
Entities.SiteCollection sc = new Entities.SiteCollection()
{
Id = id.ToString(),
Owner = site.Owner,
Template = strTemplate,
Title = site.Title,
Active = false,
Url = site.Url
};
var added = await siteCollectionStore.AddAsync(sc);
sites.Add(sc);
}
catch (System.Exception ex)
{
throw ex;
}
}
}
return sites;
};
}
However the following lines, I am repeating them on every method:
var tenant = await TenantHelper.GetActiveTenant();
var siteCollectionStore = CosmosStoreFactory.CreateForEntity<TenantManagementWebApi.Entities.SiteCollection>();
await siteCollectionStore.RemoveAsync(x => x.Title != string.Empty); // Removes all the entities that match the criteria
string domainUrl = tenant.TestSiteCollectionUrl;
string tenantName = domainUrl.Split('.')[0];
string tenantAdminUrl = tenantName + "-admin.sharepoint.com";
KeyVaultHelper keyVaultHelper = new KeyVaultHelper();
await keyVaultHelper.OnGetAsync(tenant.SecretIdentifier);
I will have lots of API controllers on my project
Is there an easy way (not refactor as a method), to make my code cleaner and inject the variables I need without copying and pasting every single time?
I am working on a module where I need to fetch members of an Active Directory group. This functionality already exists in the project but it was built for .Net3.5. The same is not working for .Net4.5. After some googling I found that I need to use "Principal Context" object to get the Directory entry object.
The problem here is, I need to do the testing in Test AD, which is different from my production AD.
The old way I used was allowing me to specify the test AD server path,
DirectoryEntry entry = new DirectoryEntry(ADLdapPath, ADAdminUser, ADAdminPassword, AuthenticationTypes.Secure);
Can anyone please help me find a way to specify LDAP path(AD server path) while creating "Principal Context" so that I can do the testing in Test environment.
I've used the following helper (modified) which is part of my AD tool belt to create PrincipalContext for working with AD. This should get you started. Modify it to suit your needs. Hope it helps.
public class ADHelper {
public static PrincipalContext CreatePrincipalContext(string domain = null) {
string container = null;
if (IsNullOrWhiteSpace(domain)) {
domain = GetCurrentDnsSuffix();
if (domain != null && domain.EndsWith(".com", StringComparison.InvariantCultureIgnoreCase)) {
container = GetContainers(domain);
} else {
domain = null;
}
}
var hostName = GetHostName();
if (IsNullOrWhiteSpace(domain)) {
domain = hostName;
}
ContextType contextType;
if (domain.Equals(hostName, StringComparison.InvariantCultureIgnoreCase) &&
domain.Equals(Environment.MachineName, StringComparison.InvariantCultureIgnoreCase)) {
contextType = ContextType.Machine;
} else {
contextType = ContextType.Domain;
}
PrincipalContext principalContext = null;
if (contextType == ContextType.Machine) {
principalContext = new PrincipalContext(contextType, domain);
} else {
principalContext = new PrincipalContext(contextType, domain, container, Constants.LDAPUser, Constants.LDAPPassword);
}
return principalContext;
}
public static string GetCurrentDnsSuffix() {
string dnsHostName = null;
if (NetworkInterface.GetIsNetworkAvailable()) {
var nics = NetworkInterface.GetAllNetworkInterfaces()
.Where(ni => ni.OperationalStatus == OperationalStatus.Up);
foreach (var ni in nics) {
var networkConfiguration = ni.GetIPProperties();
var dnsSuffix = networkConfiguration.DnsSuffix;
if (dnsSuffix != null) {
dnsHostName = dnsSuffix;
break;
}
var address = networkConfiguration.DnsAddresses.FirstOrDefault();
if (address != null) {
try {
var dnsHost = Dns.GetHostEntry(address.ToString());
dnsHostName = dnsHost.HostName;
} catch (System.Net.Sockets.SocketException e) {
traceError(e);
} catch (Exception e) {
traceError(e);
}
}
}
}
return dnsHostName;
}
private static string GetContainers(string ADServer) {
string[] LDAPDC = ADServer.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < LDAPDC.GetUpperBound(0) + 1; i++) {
LDAPDC[i] = string.Format("DC={0}", LDAPDC[i]);
}
String ldapdomain = Join(",", LDAPDC);
return ldapdomain;
}
public static string GetHostName() {
var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
return ipProperties.HostName;
}
}
I can then use it in something like this
public static List<string> GetAllUserNames(string domain = null) {
List<string> userNames = new List<string>();
using (var principalContext = createPrincipalContext(domain)) {
//Get a list of user names in MyDomain that match filter
using (UserPrincipal userPrincipal = new UserPrincipal(principalContext)) {
using (PrincipalSearcher principalSearcher = new PrincipalSearcher(userPrincipal)) {
var results = principalSearcher
.FindAll()
.Where(c =>
(c is UserPrincipal) &&
(c as UserPrincipal).Enabled.GetValueOrDefault(false) &&
!string.IsNullOrEmpty(c.DisplayName)
);
foreach (UserPrincipal p in results) {
var temp = p.StructuralObjectClass;
string value = string.Format("{0} ({1})", p.DisplayName, p.EmailAddress ?? Join("\\", p.Context.Name, p.SamAccountName));
userNames.Add(value);
}
}
}
}
return userNames;
}
I using the following code to get the groups of ActiveDirectory.
public static Task<List<String>> GetGroups(String domain = "")
{
return (Task.Factory.StartNew<List<String>>(() =>
{
List<String> list = new List<String>();
try
{
if (String.IsNullOrWhiteSpace(domain))
{
SelectQuery sQuery = new SelectQuery("Win32_Group", "LocalAccount=\"true\"");
ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(sQuery);
list.AddRange(mSearcher.Get().Cast<ManagementObject>().Select(x => x["Name"].ToString()));
}
else
{
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://" + domain);
DirectorySearcher searcher = new DirectorySearcher(directoryEntry, "(&(objectClass=group))");
searcher.SearchScope = SearchScope.Subtree;
list.AddRange(searcher.FindAll().Cast<SearchResult>().Select(x => x.GetDirectoryEntry().Name.Replace("CN=", String.Empty)));
}
}
catch (COMException e)
{
Logger.WriteException(e);
}
return (list.OrderBy(x => x).ToList());
}));
}
The code works well but dit not return the groups that are declared in an Organizational Unit...
How can I get all group including those that are into OU ?
Thanks in advance
I want to Add remove a user from a group in System.DirectoryServices.Protocol namespace.
I have the samples mentioned here :
link to my other question
But can't find an exampel fo how to add and remove a user from a group using S.DS.P.
Does anyone know of any samples for this operation?
Thanks,
Cal-
You'd just want to send a ModifyRequest on the member attribute with a DirectoryAttributeOperation.Add. The value you should pass is the DN of the user you want to add to the group
Here a example to add a object to a group.
public static void AddObjectToGroup(string objectName, string groupName)
{
// var credential = new NetworkCredential();
// var identifier = new LdapDirectoryIdentifier("");
using (var connection = new LdapConnection("company.com"))
{
connection.SessionOptions.StartTransportLayerSecurity(null);
connection.Bind();
string objectDn = null;
var request = new SearchRequest("DC=company,DC=com", $"Name={objectName}", SearchScope.Subtree, "distinguishedName");
var response = (SearchResponse)connection.SendRequest(request);
if (response != null)
{
var enumerator = response.Entries.GetEnumerator();
enumerator.Reset();
if (enumerator.MoveNext() && enumerator.Current is SearchResultEntry entry)
{
objectDn = entry.Attributes["distinguishedName"].GetValues(typeof(string)).Select(x => (string)x).FirstOrDefault();
}
}
Log.Information($"object DN: {objectDn}");
string groupDn = null;
request = new SearchRequest("DC=company,DC=com", $"Name={groupName}", SearchScope.Subtree, "distinguishedName");
response = (SearchResponse)connection.SendRequest(request);
if (response != null)
{
var enumerator = response.Entries.GetEnumerator();
enumerator.Reset();
if (enumerator.MoveNext() && enumerator.Current is SearchResultEntry entry)
{
groupDn = entry.Attributes["distinguishedName"].GetValues(typeof(string)).Select(x => (string)x).FirstOrDefault();
}
}
Log.Information($"group DN: {groupDn}");
request = new SearchRequest("DC=company,DC=com", $"(&(objectCategory=Group)(distinguishedName={groupDn}))", SearchScope.Subtree);
response = (SearchResponse)connection.SendRequest(request);
if (response != null && !string.IsNullOrWhiteSpace(objectDn))
{
var members = response.Entries[0].Attributes["member"];
var existing = new List<string>();
for (int i = 0; i < members.Count; i++)
{
existing.Add(members[i].ToString());
}
if (existing.Contains(objectDn)) return;
var dam = new DirectoryAttributeModification { Name = "member" };
dam.Add(objectDn);
dam.Operation = DirectoryAttributeOperation.Add;
var mr = new ModifyRequest(groupDn, dam);
var dr = connection.SendRequest(mr);
Log.Information($"Add Response: {dr.ResultCode.ToString()}");
}
}
}
Just for those who follow, here is how I actually solved the problem using System.DirectoryServices.AccountManagement
string adServer = "";
string adServerUser = "";
string adServerPassword = "";
string adServerContainer = "";
GetSettings( ref adServer, ref adServerUser, ref adServerPassword, ref adServerContainer );
if ( ((!string.IsNullOrEmpty(adServer) && !string.IsNullOrEmpty(adServerUser)) && !string.IsNullOrEmpty(adServerPassword)) && !string.IsNullOrEmpty(adServerContainer))
{
try
{
using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, adServer, adServerContainer, adServerUser, adServerPassword))
{
using (GroupPrincipal group = GroupPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, this.textBox_GroupAdd.Text))
{
if (group == null)
{
FlexibleMessageBox.Show("group could not be found");
return;
}
PrincipalSearchResult<Principal> x = group.GetMembers();
using (UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, this.textBox_adName.Text))
{
string userSid = string.Format("<SID={0}>", ToSidString(user));
DirectoryEntry groupDirectoryEntry = (DirectoryEntry) group.GetUnderlyingObject();
groupDirectoryEntry.Properties["member"].Add(userSid);
groupDirectoryEntry.CommitChanges();
}
}
}
}
catch (Exception ex)
{
FlexibleMessageBox.Show(ex.ToString());
}
FlexibleMessageBox.Show("group add done");
}
and here is the guts of the remove from group
using (UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, this.textBox_adName.Text))
{
string userSid = string.Format("<SID={0}>", ToSidString(user));
DirectoryEntry groupDirectoryEntry = (DirectoryEntry) group.GetUnderlyingObject();
groupDirectoryEntry.Properties["member"].Remove(userSid);
groupDirectoryEntry.CommitChanges();
}
Given a group like this in Active Directory:
MainGroup
GroupA
User1
User2
GroupB
User3
User4
I can easily determine if User3 is member of MainGroup or any of its subgroups with code like this:
using System;
using System.DirectoryServices;
static class Program {
static void Main() {
DirectoryEntry user = new DirectoryEntry("LDAP://CN=User3,DC=X,DC=y");
string filter = "(memberOf:1.2.840.113556.1.4.1941:=CN=MainGroup,DC=X,DC=y)";
DirectorySearcher searcher = new DirectorySearcher(user, filter);
searcher.SearchScope = SearchScope.Subtree;
var r = searcher.FindOne();
bool isMember = (r != null);
}
}
I would like to know if there is a similar way to get all the users that are member of a group or any of its subgroups, i.e. in the example for MainGroup get User1, User2, User3 and User4.
The obvious way of getting all the users is to recursively query each subgroup, but I was wondering if there is an easier way to do it.
Using the same approach with the memberOf:1.2.840.113556.1.4.1941: filter, but using the domain root instead of the user as a search base is not feasible, as the query takes too long (probably it computes all the group memberships recursively for all users in the domain and checks if they are member of the given group).
Which is the best way to get all members of a group, including its subgroups?
Just in case this might benefit someone else: here is the solution I ended up with. It is just a recursive search, with some extra checks to avoid checking the same group or user twice, e.g. if groupA is member of groupB and groupB is member of groupA or a user is member of more than one group.
using System;
using System.DirectoryServices;
using System.Collections.Generic;
static class Program {
static IEnumerable<SearchResult> GetMembers(DirectoryEntry searchRoot, string groupDn, string objectClass) {
using (DirectorySearcher searcher = new DirectorySearcher(searchRoot)) {
searcher.Filter = "(&(objectClass=" + objectClass + ")(memberOf=" + groupDn + "))";
searcher.PropertiesToLoad.Clear();
searcher.PropertiesToLoad.AddRange(new string[] {
"objectGUID",
"sAMAccountName",
"distinguishedName"});
searcher.Sort = new SortOption("sAMAccountName", SortDirection.Ascending);
searcher.PageSize = 1000;
searcher.SizeLimit = 0;
foreach (SearchResult result in searcher.FindAll()) {
yield return result;
}
}
}
static IEnumerable<SearchResult> GetUsersRecursively(DirectoryEntry searchRoot, string groupDn) {
List<string> searchedGroups = new List<string>();
List<string> searchedUsers = new List<string>();
return GetUsersRecursively(searchRoot, groupDn, searchedGroups, searchedUsers);
}
static IEnumerable<SearchResult> GetUsersRecursively(
DirectoryEntry searchRoot,
string groupDn,
List<string> searchedGroups,
List<string> searchedUsers) {
foreach (var subGroup in GetMembers(searchRoot, groupDn, "group")) {
string subGroupName = ((string)subGroup.Properties["sAMAccountName"][0]).ToUpperInvariant();
if (searchedGroups.Contains(subGroupName)) {
continue;
}
searchedGroups.Add(subGroupName);
string subGroupDn = ((string)subGroup.Properties["distinguishedName"][0]);
foreach (var user in GetUsersRecursively(searchRoot, subGroupDn, searchedGroups, searchedUsers)) {
yield return user;
}
}
foreach (var user in GetMembers(searchRoot, groupDn, "user")) {
string userName = ((string)user.Properties["sAMAccountName"][0]).ToUpperInvariant();
if (searchedUsers.Contains(userName)) {
continue;
}
searchedUsers.Add(userName);
yield return user;
}
}
static void Main(string[] args) {
using (DirectoryEntry searchRoot = new DirectoryEntry("LDAP://DC=x,DC=y")) {
foreach (var user in GetUsersRecursively(searchRoot, "CN=MainGroup,DC=x,DC=y")) {
Console.WriteLine((string)user.Properties["sAMAccountName"][0]);
}
}
}
}
static List<SearchResult> ad_find_all_members(string a_sSearchRoot, string a_sGroupDN, string[] a_asPropsToLoad)
{
using (DirectoryEntry de = new DirectoryEntry(a_sSearchRoot))
return ad_find_all_members(de, a_sGroupDN, a_asPropsToLoad);
}
static List<SearchResult> ad_find_all_members(DirectoryEntry a_SearchRoot, string a_sGroupDN, string[] a_asPropsToLoad)
{
string sDN = "distinguishedName";
string sOC = "objectClass";
string sOC_GROUP = "group";
string[] asPropsToLoad = a_asPropsToLoad;
Array.Sort<string>(asPropsToLoad);
if (Array.BinarySearch<string>(asPropsToLoad, sDN) < 0)
{
Array.Resize<string>(ref asPropsToLoad, asPropsToLoad.Length+1);
asPropsToLoad[asPropsToLoad.Length-1] = sDN;
}
if (Array.BinarySearch<string>(asPropsToLoad, sOC) < 0)
{
Array.Resize<string>(ref asPropsToLoad, asPropsToLoad.Length+1);
asPropsToLoad[asPropsToLoad.Length-1] = sOC;
}
List<SearchResult> lsr = new List<SearchResult>();
using (DirectorySearcher ds = new DirectorySearcher(a_SearchRoot))
{
ds.Filter = "(&(|(objectClass=group)(objectClass=user))(memberOf=" + a_sGroupDN + "))";
//ds.PropertiesToLoad.Clear();
ds.PropertiesToLoad.AddRange(asPropsToLoad);
//ds.PageSize = 1000;
//ds.SizeLimit = 0;
foreach (SearchResult sr in ds.FindAll())
lsr.Add(sr);
}
for(int i=0;i<lsr.Count;i++)
if (lsr[i].Properties.Contains(sOC) && lsr[i].Properties[sOC].Contains(sOC_GROUP))
lsr.AddRange(ad_find_all_members(a_SearchRoot, (string)lsr[i].Properties[sDN][0], asPropsToLoad));
return lsr;
}
static void Main(string[] args)
{
foreach (var sr in ad_find_all_members("LDAP://DC=your-domain,DC=com", "CN=your-group-name,OU=your-group-ou,DC=your-domain,DC=com", new string[] { "sAMAccountName" }))
Console.WriteLine((string)sr.Properties["distinguishedName"][0] + " : " + (string)sr.Properties["sAMAccountName"][0]);
}
To get the members recursively take this (the trick is GetMembers(true) instead of false which is the default value):
private List<string> GetGroupMembers(string groupName)
{
var members = new List<string>();
try
{
using (var pc = new PrincipalContext(ContextType.Domain, Common.THE_DOMAIN))
{
var gp = GroupPrincipal.FindByIdentity(pc, groupName);
if (gp == null) return members;
foreach (Principal p in gp.GetMembers(true))
members.Add(p.Name);
members.Sort();
}
}
catch (Exception)
{
return new List<string>();
}
return members;
}
I also wanted to know if a user or a computer is in an ActiveDirectory group. And this worked for me also with nested groups (it is part of a WebService but you can use the code also in a standalone application):
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
[HttpGet]
[Route("IsUserInGroup")]
public HttpResponseMessage IsUserInGroup(string userName, string groupName)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
try
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, Common.THE_DOMAIN))
{
var gp = GroupPrincipal.FindByIdentity(pc, groupName);
var up = UserPrincipal.FindByIdentity(pc, userName);
if (gp == null)
{
response.Content = Common.ConvertToJsonContent($"Group '{groupName}' not found in Active Directory");
response.StatusCode = HttpStatusCode.NotFound;
return response;
}
if (up == null)
{
response.Content = Common.ConvertToJsonContent($"User '{userName}' not found in Active Directory");
response.StatusCode = HttpStatusCode.NotFound;
return response;
}
DirectoryEntry user = new DirectoryEntry($"LDAP://{up.DistinguishedName}");
DirectorySearcher mySearcher = new DirectorySearcher(user)
{
SearchScope = System.DirectoryServices.SearchScope.Subtree,
Filter = $"(memberOf:1.2.840.113556.1.4.1941:={gp.DistinguishedName})"
};
SearchResult result = mySearcher.FindOne();
response.StatusCode = HttpStatusCode.OK;
response.Content = Common.ConvertToJsonContent(result != null);
}
}
catch (Exception ex)
{
response.StatusCode = HttpStatusCode.BadRequest;
response.Content = Common.ConvertToJsonContent($"{MethodBase.GetCurrentMethod().Name}: {ex.Message}");
}
return response;
}
[HttpGet]
[Route("IsComputerInGroup")]
public HttpResponseMessage IsComputerInGroup(string computerName, string groupName)
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
try
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, Common.THE_DOMAIN))
{
var gp = GroupPrincipal.FindByIdentity(pc, groupName);
var cp = ComputerPrincipal.FindByIdentity(pc, computerName);
if (gp == null)
{
response.Content = Common.ConvertToJsonContent($"Group '{groupName}' not found in Active Directory");
response.StatusCode = HttpStatusCode.NotFound;
return response;
}
if (cp == null)
{
response.Content = Common.ConvertToJsonContent($"Computer '{computerName}' not found in Active Directory");
response.StatusCode = HttpStatusCode.NotFound;
return response;
}
DirectoryEntry computer = new DirectoryEntry($"LDAP://{cp.DistinguishedName}");
DirectorySearcher mySearcher = new DirectorySearcher(computer)
{
SearchScope = System.DirectoryServices.SearchScope.Subtree,
Filter = $"(memberOf:1.2.840.113556.1.4.1941:={gp.DistinguishedName})"
};
SearchResult result = mySearcher.FindOne();
response.StatusCode = HttpStatusCode.OK;
response.Content = Common.ConvertToJsonContent(result != null);
}
}
catch (Exception ex)
{
response.StatusCode = HttpStatusCode.BadRequest;
response.Content = Common.ConvertToJsonContent($"{MethodBase.GetCurrentMethod().Name}: {ex.Message}");
}
return response;
}