I have a scenario where I need to access a remote machine to programmatically add and delete Windows users accounts. The remote machine is a "spare workstation" that I need to remotely configure, to be ready just in case the main workstation need to be replaced - so no security bypass or malicious software here :)
I know user/password of remote machine administrator, and I'm able to retrieve a complete list of existing users account using WMI Win32_UserAccount. Now, I'm trying to obtain an UserPrincipal object for each user (to eventually delete it), but I'm getting exceptions for all of my attempts.
Attempt #1:
PrincipalContext context = new PrincipalContext(ContextType.Domain, "xxx.xxx.xxx.xxx" /*remote IP Address*/); UserPrincipal user = (UserPrincipal.FindByIdentity(context, "userName")); // Do something with user, like user.Delete();
In this case I always get an exception in the first line:
System.DirectoryServices.AccountManagement.PrincipalServerDownException was caught Message=The server could not be contacted.
Source=System.DirectoryServices.AccountManagement StackTrace: in System.DirectoryServices.AccountManagement.PrincipalContext.ReadServerConfig(String serverName, ServerProperties& properties) in System.DirectoryServices.AccountManagement.PrincipalContext.DoServerVerifyAndPropRetrieval() in System.DirectoryServices.AccountManagement.PrincipalContext..ctor(ContextType contextType, String name, String container, ContextOptions options, String userName, String password) in System.DirectoryServices.AccountManagement.PrincipalContext..ctor(ContextType contextType, String name, String container, String userName, String password) InnerException: System.DirectoryServices.Protocols.LdapException Message=The LDAP server is unavailable. Source=System.DirectoryServices.Protocols ErrorCode=81 StackTrace: in System.DirectoryServices.Protocols.LdapConnection.Connect() in System.DirectoryServices.Protocols.LdapConnection.SendRequestHelper(DirectoryRequest request, Int32& messageID) in System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request, TimeSpan requestTimeout) in System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request) in System.DirectoryServices.AccountManagement.PrincipalContext.ReadServerConfig(String serverName, ServerProperties& properties) InnerException:Attempt #2:
PrincipalContext context = new PrincipalContext(ContextType.Machine, "xxx.xxx.xxx.xxx" /*remote IP Address*/); UserPrincipal user = (UserPrincipal.FindByIdentity(context, "userName")); // Do something with user, like user.Delete();
In this case I always get an exception in the second line:
System.IO.FileNotFoundException was caught Message=Network path not found.
Source=Active Directory StackTrace: in System.DirectoryServices.Interop.UnsafeNativeMethods.IAds.GetInfo() in System.DirectoryServices.DirectoryEntry.RefreshCache() in System.DirectoryServices.AccountManagement.PrincipalContext.DoMachineInit() in System.DirectoryServices.AccountManagement.PrincipalContext.Initialize() in System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx() in System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate) in System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, String identityValue) in System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, String identityValue) InnerException:
I've tried different signatures of PrincipalContext object (with domain name instead of IP address, with user name and password, ...) but I always get exceptions on both attempts.
Am I missing some instructions? Do I need to use impersonation to gain full acces to remote machine before to create PrincipalContext object? Any other ways to accomplish what I'am trying to do? (that is, access a remote machine to add/remove Windows account)