The purpose of group policies is to be able to centrally manage settings on client computers. If your GPO sets some registry settings on the client computer they will get reapplied if the settings are changed locally. I believe that GPO's by default are refreshed every 90 minutes (or 5 minutes on domain controllers).
If you want to use GPO's to manage specific settings in registry you should store the application setting in one place and the settings from the GPO in another place. Often you have "parallel" registry structures for settings and policy. When your application queries a setting it should first determine if the setting is controlled by a policy and then use the policy value. Otherwise it should use the local value.
From your question it seems that you want to be able to do the opposite, that is, you want the local settings to take precedence over the GPO. In that case I don't see why you have the GPO in the first place since it will always be overruled by the local setting.
If you don't want to wait 90 minutes but still want to test what happens when your GPO is applied you can use the gpupdate tool to manually refresh the GPO.
It seems that the user account with which the Active Directory tries to authenticate "you" does not exist as your DirectoryServicesCOMException
reports it.
DirectoryServicesCOMException: Logon failure: unkonwn user name or bad password.
Look at your code sample, it seems you're not using impersonation, hence the security protocol of the Active Directory take into account the currently authenticated user. Make this user yourself, then if you happen not to be defined on both of your domain roots, one of them doesn't know you, which throws this kind of exception.
On the other hand, using impersonation might solve the problem here, since you're saying that your Windows Service account has the rights to query both your roots under the same forest, then you have to make sure the authenticated user is your Windows Service.
In clear, this means that without impersonation, you cannot guarantee that the authenticated user IS your Windows Service. To make sure about it, impersonation is a must-use.
Now, regarding the two roots
- ktregression.com;
- ktregression.root.
These are two different and independant roots. Because of this, I guess you should go with two instances of the DirectoryEntry
class fitting one for each root.
After having instantiated the roots, you need to search for the user you want to find, which shall be another different userName than the one that is impersonated.
We now have to state whether a user can be defined on both roots. If it is so, you will need to know when it is better to choose one over the other. And that is of another concern.
Note
For the sake of simplicity, I will take it that both roots' name are complete/full as you mentioned them.
private string _dotComRootPath = "LDAP://ktregression.com";
private string _dotRootRootPath = "LDAP://ktregression.root";
private string _serviceAccountLogin = "MyWindowsServiceAccountLogin";
private string _serviceAccountPwd = "MyWindowsServiceAccountPassword";
public string GetUserDomain(string rootPath, string login) {
string userDomain = null;
using (DirectoryEntry root = new DirectoryEntry(rootPath, _serviceAccountLogin, _serviceAccountPwd))
using (DirectorySearcher searcher = new DirectorySearcher()) {
searcher.SearchRoot = root;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("nETBIOSName");
searcher.Filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", login);
SearchResult result = null;
try {
result = searcher.FindOne();
if (result != null)
userDomain = (string)result.GetDirectoryEntry()
.Properties("nETBIOSName").Value;
} finally {
dotComRoot.Dispose();
dotRootRoot.Dispose();
if (result != null) result.Dispose();
}
}
return userDomain;
}
And using it:
string userDomain = (GetUserDomain(_dotComRoot, "searchedLogin")
?? GetUserDomain(_dotRootRoot, "searchedLogin"))
?? "Unknown user";
Your exception is thrown only on the second DirectoryEntry
initilization which suggests that your default current user doesn't have an account defined on this root.
EDIT #1
Please see my answer to your other NetBIOS Name related question below:
C# Active Directory: Get domain name of user?
where I provide a new and probably easier solution to your concern.
Let me know if you have any further question. =)
Best Answer
The security warning is very likely a red herring. We can go into why it's coming up, but I'm more interested in talking about the script executing during logon first.
Logon to a client computer with a user account that should be executing the script and run the "Resultant Set of Policy" tool (from a blank MMC, add the "Resultant Set of Policy" snap-in, then highlight and right-click the "Resultant Set of Policy" in the scope pane and choose "Generate RSoP Data..." Take all defaults...)
I'm assuming you haven't played with the NTFS ACLs on the script or the ACLs on the GPO itself.
My gut says that this is a GPO scoping issue. Have a look, after you've gathered the policies, and see if the script is being placed in the list of scripts to be executed for the user. Right-click the "User Configuration" node in the scope pane, after you've gathered the RSoP data, and examine the list of GPOs associated with the user. Do you see the GPO containing your script in that list?
Assuming you do see the GPO applying and do see the script listed in the logon scripts to be executed for the user, I'd head over to the Application Event Log next and see if USERINIT is logging anything during logon about problems executing the script.
Assuming you don't see your GPO applying to the user, I'd think about where you have the GPO linked in relation to the user accounts (this is the "scoping issue" I spoke about). The GPO must be linked at the OU the user object is located within, at a parent OU of the OU the user object is located within, at the top of the domain, or at the site object associated with the IP subnet from which the client computer's IP address has been assigned.
If this doesn't make sense and you're still not seeing what you'd expect, post some description of the logical topology of the objects in question-- i.e. a tree diagram showing the domain, and any child OU's that contain the user objects in question, and an annotation about where you linked the GPO.