T
tim (dot) campbell (at) hyperlink (dash) interacti
(Apologies for the crossposting, but I wasn't sure which group would be
best to post this to)
I have a problem with some C#/.NET (v1.1) code that I've inherited as
part of a project that my company won to redevelop an existing website.
The code in question uses directory services and the LDAP provider to
connect to an Active Directory server, and create/update user account
details.
The code runs perfectly on my development PC, which runs Windows XP Pro,
but fails with a COMException when I try to run it on the batch server,
which runs Windows 2000 Server. Further investigation has revealed that
it apparently fails in the same way on any machine running Windows 2000
Server - I've tried it on five other machines with exactly the same results.
The relevant section of code is reproduced below:
DirectoryEntry accountRoot = new DirectoryEntry(config.adRootPath,
config.adConnectionUsername,
config.adConnectionPassword,
AuthenticationTypes.ServerBind);
DirectoryEntry accountGroup = new DirectoryEntry(
config.adServer
+ config.adGroupObject,
config.adConnectionUsername,
config.adConnectionPassword,
AuthenticationTypes.ServerBind);
try
{
accountRoot.RefreshCache();
accountGroup.RefreshCache();
}
catch (Exception ex)
{
WriteErrorLog("Failed to refresh caches:\n\n" + ex.ToString());
return;
}
PropertyValueCollection groupMembers =
accountGroup.Properties["member"];
DirectoryEntry accountEntry = null;
try
{
accountEntry = accountRoot.Children.Find("CN=" + accountName,
"user");
}
catch(COMException)
{
// code ommited for brevity
}
if( accountEntry != null )
{
try
{
// Set mandatory account elements
accountEntry.Properties["sAMAccountName"].Value = accountName;
// Set some additional properties
accountEntry.Properties["userAccountControl"].Value = 0x10240;
accountEntry.Properties["userPrincipalName"].Value = accountName
+ "@" + config.adDomain;
object[] invocationArg = new object[]{accountPwd};
try
{
accountEntry.Invoke("setPassword", invocationArg);
}
catch (Exception e)
{
WriteErrorLog("Failed to set password for account \""
+ accountName + "\":\n\n" + e.ToString());
return;
}
}
catch( COMException commitException )
{
WriteErrorLog("Failed commit changes to Active Directory
server:\n\n" + commitException.ToString());
return;
}
}
The problematic line is the one that calls the Invoke method on the
DirectoryEntry object. At this point, on each of the Windows 2000 Server
machines, it fails with the following exception:
System.Reflection.TargetInvocationException: Exception has been thrown
by the target of an invocation. --->
System.Runtime.InteropServices.COMException (0x8007052E): The handle
specified is invalid
--- End of inner exception stack trace ---
at System.RuntimeType.InvokeDispMethod(String name, BindingFlags
invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers,
Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags
invokeAttr, Binder binder, Object target, Object[] args,
ParameterModifier[] modifiers, CultureInfo culture, String[]
namedParameters)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr,
Binder binder, Object target, Object[] args)
at System.DirectoryServices.DirectoryEntry.Invoke(String methodName,
Object[] args)
at ADUpdater.ADUpdater.Main(String[] args)
I've been messing with this on and off for a few days now, and I'm not
really getting anywhere. Does anyone have any idea why this would be
failing on the Win2k Server machines? Input data and config is identical
in all cases, and I'm connecting to the Active Directory server using an
admin account's username and password.
Cheers,
Tim
best to post this to)
I have a problem with some C#/.NET (v1.1) code that I've inherited as
part of a project that my company won to redevelop an existing website.
The code in question uses directory services and the LDAP provider to
connect to an Active Directory server, and create/update user account
details.
The code runs perfectly on my development PC, which runs Windows XP Pro,
but fails with a COMException when I try to run it on the batch server,
which runs Windows 2000 Server. Further investigation has revealed that
it apparently fails in the same way on any machine running Windows 2000
Server - I've tried it on five other machines with exactly the same results.
The relevant section of code is reproduced below:
DirectoryEntry accountRoot = new DirectoryEntry(config.adRootPath,
config.adConnectionUsername,
config.adConnectionPassword,
AuthenticationTypes.ServerBind);
DirectoryEntry accountGroup = new DirectoryEntry(
config.adServer
+ config.adGroupObject,
config.adConnectionUsername,
config.adConnectionPassword,
AuthenticationTypes.ServerBind);
try
{
accountRoot.RefreshCache();
accountGroup.RefreshCache();
}
catch (Exception ex)
{
WriteErrorLog("Failed to refresh caches:\n\n" + ex.ToString());
return;
}
PropertyValueCollection groupMembers =
accountGroup.Properties["member"];
DirectoryEntry accountEntry = null;
try
{
accountEntry = accountRoot.Children.Find("CN=" + accountName,
"user");
}
catch(COMException)
{
// code ommited for brevity
}
if( accountEntry != null )
{
try
{
// Set mandatory account elements
accountEntry.Properties["sAMAccountName"].Value = accountName;
// Set some additional properties
accountEntry.Properties["userAccountControl"].Value = 0x10240;
accountEntry.Properties["userPrincipalName"].Value = accountName
+ "@" + config.adDomain;
object[] invocationArg = new object[]{accountPwd};
try
{
accountEntry.Invoke("setPassword", invocationArg);
}
catch (Exception e)
{
WriteErrorLog("Failed to set password for account \""
+ accountName + "\":\n\n" + e.ToString());
return;
}
}
catch( COMException commitException )
{
WriteErrorLog("Failed commit changes to Active Directory
server:\n\n" + commitException.ToString());
return;
}
}
The problematic line is the one that calls the Invoke method on the
DirectoryEntry object. At this point, on each of the Windows 2000 Server
machines, it fails with the following exception:
System.Reflection.TargetInvocationException: Exception has been thrown
by the target of an invocation. --->
System.Runtime.InteropServices.COMException (0x8007052E): The handle
specified is invalid
--- End of inner exception stack trace ---
at System.RuntimeType.InvokeDispMethod(String name, BindingFlags
invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers,
Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags
invokeAttr, Binder binder, Object target, Object[] args,
ParameterModifier[] modifiers, CultureInfo culture, String[]
namedParameters)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr,
Binder binder, Object target, Object[] args)
at System.DirectoryServices.DirectoryEntry.Invoke(String methodName,
Object[] args)
at ADUpdater.ADUpdater.Main(String[] args)
I've been messing with this on and off for a few days now, and I'm not
really getting anywhere. Does anyone have any idea why this would be
failing on the Win2k Server machines? Input data and config is identical
in all cases, and I'm connecting to the Active Directory server using an
admin account's username and password.
Cheers,
Tim