views:

97

answers:

1

Due to our clients authentication and network topology we have a number of Windows Servers in a DMZ without Active Directory or a Domain Controller. Corporate policy stipulates that passwords must change once a month. Our dev machines are in AD (not in the DMZ) so we run into the situation that we have to synchronise our usernames and passwords on each of the DMZ machines with our AD credentials every month. There are a lot of DMZ machines.

I want to use a simple console app to change the user passwords on all the DMZ machines for a given user. So far, I have the following code:

using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
class Program{
    static void Main(){
        List<string> remoteHosts = new List<string> { "RemoteHostA", "RemoteHostB", "RemoteHostC" };
        remoteHosts.ForEach(host => ChangePassword(host, "username", "oldPassword", "newPassword"));
    }
    static void ChangePassword(string host, string username, string oldPassword, string newPassword){
        using (var context = new PrincipalContext(ContextType.Machine, host, username, newPassword))
            using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username))
                user.ChangePassword(oldPassword, newPassword);
    }
}

The problem is that this only works if the password has not already changed on the dev machine where it is being run from. Because the context that is used, first has to authenticate with the dev machine in order to gain access to the network, then it has to gain access to the remote (DMZ) machine using the same context before changing the password.

How can I alter the method to use a new-password-context to gain access to the network and an old-password-context to gain access to the remote host?

Note to Title Editors: The code depends on System.DirectoryServices.AccountManagement which is an FX 3.5 assembly not 3.0.

+1  A: 

Can you use WMI directly to achieve this? A quick search showed up this page

Note : It is a long time since I did anything with WMI, but I do remember being able to call it from a C# app, if that's how you are comfortable using it. (Check in System.Management)

ZombieSheep
+1 The code example in your link looks promising.
grenade