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)
Answer
If you simply want to remove the account, why not use Directory Services instead:
using System.DirectoryServices;
DirectoryEntry deParent = new DirectoryEntry("WinNT://[computername]",
@"[domain\adminname", "password");
DirectoryEntry deToRemove = deParent.Children.Find("usernametoremove");
deParent.Children.Remove(deToRemove);
No comments:
Post a Comment