We have a .net application which makes a WMI query via ManagementObjectSearcher. This was working until recently and I don't know what changed.
ErrorCode = AccessDenied [System.Management.ManagementStatus]
Message = "Access denied "
Data (EMPTY DICTIONARY) [System.Collections.ListDictionaryInternal], OBJ #34963204
InnerException = (NULL)
TargetSite = Void ThrowWithExtendedInfo(System.Management.ManagementStatus) [System.Reflection.RuntimeMethodInfo]
StackTrace = " at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
at System.Management.ManagementScope.InitializeGuts(Object o)
at System.Management.ManagementScope.Initialize()
at System.Management.ManagementObjectSearcher.Initialize()
at System.Management.ManagementObjectSearcher.Get()
After searching for answers from others, I found permissions are required for the WMI namespace being queried in wmimgmt.msc. The thing is the Administrators user group already has full access to all the namespaces and the user running the application is inside it.
var groupFilter = string.Join(" or ", s_serverAdminWindowsGroups.Select(groupName => $#"GroupComponent='Win32_Group.Domain=""{s_machineName}"",Name=""{groupName}""'"));
var query = new ObjectQuery($#"SELECT PartComponent FROM Win32_GroupUser
where ({groupFilter}) and
PartComponent='Win32_{(isSystemAccount ? "System" : "User")}Account.Domain=""{userDomainName}"",Name=""{userName}""'");
using (var search = new ManagementObjectSearcher(query))
using (ManagementObjectCollection results = search.Get())
return results.Count > 0;
I tried adding the user directly to the WMI permissions and it now works. But it would be very tedious to have to do this for every user.
Good Day All,
I have been asked to write out some code to find a computer object in AD I haven't been given the OU's that these objects could be in (which isn't helpful at all - obviously). I've determined that I can remotely connect to the AD server with the lines:
DirectoryEntry startingPoint = new DirectoryEntry("LDAP://DC=Zone,DC=Corp,DC=COM", "UserName", "Password");
//Find all OUs
DirectorySearcher searcher = new DirectorySearcher(startingPoint);
searcher.Filter = "(objectCategory=Computer)";
foreach (SearchResult result in searcher.FindAll())
{
}
Unfortunately, the only information I do have is that all the objects will be no further than 3 OU's deep. So I'd like to know how to go through each of the OU's going that deep in each one I come to until I find the designated host name. I'm not exactly sure how to work that out. Any assistance would be appreciated.
First, I would change the SearchScope to Subtree and then include the hostname as part of the filter. I would then use FindOne() instead of FindAll():
DirectoryEntry startingPoint = new DirectoryEntry("LDAP://DC=Zone,DC=Corp,DC=COM", "UserName", "Password");
DirectorySearcher searcher = new DirectorySearcher(startingPoint)
{
SearchScope = SearchScope.Subtree,
Filter = $"(&(objectCategory=Computer)(cn={hostname}))"
};
SearchResult result = searcher.FindOne();
Im using c#, DirectoryEntry (System.DirectoryServices) to read and write a users of objectClass "inetOrgPerson".
This works well, until i want to write the Attributes "labeledURI" or "displayName".
Actually, i can write them once, but the second time it fails. I think that DirectoryEntry has trouble to read them from the Ldap.
I can provide more Code, but i hope this little example gives an idea.
PseudoCode here:
DirectoryEntry deFound = null;
DirectoryEntry de = new DirectoryEntry(a_strLdapServer + "/" + a_strLdapBasePath, m_strLdapUser, m_strLdapPw, AuthenticationTypes.None);
DirectorySearcher deSearch = new DirectorySearcher();
deSearch.SearchRoot = de;
deSearch.Filter = "(&(objectClass=person) (uid=" + a_strUserName + "))";
//deSearch.PropertiesToLoad.Add("labeledURI");
SearchResultCollection results = deSearch.FindAll();
if (results.Count == 1)
{
deFound = results[0].GetDirectoryEntry();
}
//WORKS ONCE:
deFound.Properties["labeledURI"].Value = "http://www.google.com";
Throwed Exception:
deFound.Properties["labeledURI"].Value 'm_deFound.Properties["labeledURI"]' threw an exception of type 'System.Runtime.InteropServices.COMException' object
Do you know i'm doing wrong?
Figured it out!
Forget about changing ldap:// to LDAP:// or other snake oil.
The problem is hidden in Windows8 (and Server2012 as well).
when you can't access
deFound.Properties["labeledURI"]
or
deFound.Properties["displayName"]
and you're using windows8., then here is a Hotfix:
http://support.microsoft.com/kb/2802148
I'm writing a piece of code that is supposed to search the active directory for a specific users GivenName (forename) and Surname based upon their SamAccountName as the search parameter, and then return a string containing their given name and surname.
The code I have written so far is as follows:
public static string GetName(string uName)
{
StringBuilder builder = new StringBuilder();
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, "serverName"))
{
UserPrincipal user = new UserPrincipal(context);
user.SamAccountName = uName;
PrincipalSearcher srch = new PrincipalSearcher(user);
srch.QueryFilter = user;
PrincipalSearchResult<Principal> res = srch.FindAll();
foreach (UserPrincipal u in res)
{
builder.Append(u.GivenName);
builder.Append(" ");
builder.Append(u.Surname);
}
return builder.ToString();
}
}
The problem I'm having with the above code is that during run-time the line
user.SamAccountName = uName;
throws the following error: DirectoryServicesCOMException unhandled "A local error has occured"
The principal context object is created just fine, as is the user principal object, it only throws the error when executing the line mentioned above. What's even more bizarre is that this code seemed to work a couple of days ago. If anyone reading this has any ideas as to why I'm getting this error I'd be greatly appreciative!
P.S.
I resorted to asking about this as the bloody error message is a bit too cryptic to actually figure out, or at least for me anyway (a local error occured) really? Whichever developer thought that was a useful error message is an idiot.
Possible causes:
There is an issue with the computer's domain membership or authentication. For example, is the clock on the computer running the code synchronized (within 5 minutes) of the DCs in the target domain?
The user name is invalid. For example, it contains invalid characters.
I'm trying to run a simple LDAP query using directory services in .Net.
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com");
directoryEntry.AuthenticationType = AuthenticationTypes.Secure;
DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry);
directorySearcher.Filter = string.Format("(&(objectClass=user)(objectCategory=user) (sAMAccountName={0}))", username);
var result = directorySearcher.FindOne();
var resultDirectoryEntry = result.GetDirectoryEntry();
return resultDirectoryEntry.Properties["msRTCSIP-PrimaryUserAddress"].Value.ToString();
And I'm getting the following exception:
System.Runtime.InteropServices.COMException (0x80005000): Unknown error (0x80005000)
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
at System.DirectoryServices.DirectorySearcher.FindOne()
As a snippet in a Console app, this works. But when I run it as part of a WCF service (run under the same credentials), it throws the above exception.
Any suggestions?
Thanks
I had the same again and again and nothing seemed to help.
Changing the path from ldap:// to LDAP:// did the trick.
It's a permission problem.
When you run the console app, that app runs with your credentials, e.g. as "you".
The WCF service runs where? In IIS? Most likely, it runs under a separate account, which is not permissioned to query Active Directory.
You can either try to get the WCF impersonation thingie working, so that your own credentials get passed on, or you can specify a username/password on creating your DirectoryEntry:
DirectoryEntry directoryEntry =
new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com",
userName, password);
OK, so it might not be the credentials after all (that's usually the case in over 80% of the cases I see).
What about changing your code a little bit?
DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry);
directorySearcher.Filter = string.Format("(&(objectClass=user)(objectCategory=user) (sAMAccountName={0}))", username);
directorySearcher.PropertiesToLoad.Add("msRTCSIP-PrimaryUserAddress");
var result = directorySearcher.FindOne();
if(result != null)
{
if(result.Properties["msRTCSIP-PrimaryUserAddress"] != null)
{
var resultValue = result.Properties["msRTCSIP-PrimaryUserAddress"][0];
}
}
My idea is: why not tell the DirectorySearcher right off the bat what attribute you're interested in? Then you don't need to do another extra step to get the full DirectoryEntry from the search result (should be faster), and since you told the directory searcher to find that property, it's certainly going to be loaded in the search result - so unless it's null (no value set), then you should be able to retrieve it easily.
Marc
In the context of Ektron, this issue is resolved by installing the "IIS6 Metabase compatibility" feature in Windows:
Check 'Windows features' or 'Role Services' for IIS6 Metabase
compatibility, add if missing:
Ref: https://portal.ektron.com/KB/1088/
On IIS hosted sites, try recycling the app pool. It fixed my issue.
Thanks
I had the same error - in my case it was extra slash in path argument that made the difference.
BAD:
DirectoryEntry directoryEntry =
new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com/",
userName, password);
GOOD:
DirectoryEntry directoryEntry =
new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com",
userName, password);
I had this error as well and for me it was an OU with a forward slash in the name: "File/Folder Access Groups".
This forum thread pointed me in the right direction. In the end, calling .Replace("/","\\/") on each path value before use solved the problem for me.
Just FYI, I had the same error and was using the correct credentials but my LDAP url was wrong :(
I got the exact same error message and code
Just had that problem in a production system in the company where I live... A webpage that made a LDAP bind stopped working after an IP changed.
The solution...
... I installed Basic Authentication to perform the troubleshooting indicated here: https://support.microsoft.com/en-us/kb/329986
And after that, things just started to work. Even after I re-disabled Basic Authentication in the page I was testing, all other pages started working again with Windows Authentication.
Regards,
Acácio
I encounter this error when I'm querying an entry of another domain of the forrest and this entry have some custom attribut of the other domain.
To solve this error, I only need to specify the server in the url LDAP :
Path with error = LDAP://CN=MyObj,DC=DOMAIN,DC=COM
Path without error : LDAP://domain.com:389/CN=MyObj,DC=Domain,DC=COM
This Error can occur if the physical machine has run out of memory.
In my case i was hosting a site on IIS trying to access the AD, but the server had run out of memory.
I had to change my code from this:
DirectoryEntry entry = new DirectoryEntry(path, ldapUser, ldapPassword);
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchRoot = entry;
searcher.SearchScope = SearchScope.Subtree;
To this:
DirectoryEntry entry = new DirectoryEntry(path, ldapUser, ldapPassword);
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchScope = SearchScope.OneLevel;
SearchResult searchResult = searcher.FindOne();
The same error occurs if in DirectoryEntry.Patch is nothing after the symbols "LDAP//:". It is necessary to check the directoryEntry.Path before directorySearcher.FindOne(). Unless explicitly specified domain, and do not need to "LDAP://".
private void GetUser(string userName, string domainName)
{
DirectoryEntry dirEntry = new DirectoryEntry();
if (domainName.Length > 0)
{
dirEntry.Path = "LDAP://" + domainName;
}
DirectorySearcher dirSearcher = new DirectorySearcher(dirEntry);
dirSearcher.SearchScope = SearchScope.Subtree;
dirSearcher.Filter = string.Format("(&(objectClass=user)(|(cn={0})(sn={0}*)(givenName={0})(sAMAccountName={0}*)))", userName);
var searchResults = dirSearcher.FindAll();
//var searchResults = dirSearcher.FindOne();
if (searchResults.Count == 0)
{
MessageBox.Show("User not found");
}
else
{
foreach (SearchResult sr in searchResults)
{
var de = sr.GetDirectoryEntry();
string user = de.Properties["SAMAccountName"][0].ToString();
MessageBox.Show(user);
}
}
}
Spent a day on my similar issue, but all these answers didn't help.
Turned out in my case, I didn't enable Windows Authentication in IIS setting...
In my case, the problem was that I was trying to reference a DirectoryEntry's property value, even though that DirectoryEntry did not have that property at all.
If you for example, have:
var myGroup = new DirectoryEntry("LDAP://CN=mygroup,OU=mydomain....", myUsername, myPassword);
var groupManager = myGroup.Properties["managedBy"].Value.ToString();
If myGroup has no managedBy attribute set in the AD, this will result in Unknown error (0x80005000)