Friday 22 November 2019

c# - How to access remote machine to add/remove/manage users accounts?



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

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...