To set a password on a new user account Data Sync uses the DS-SetPassword
attribute to clear the UAC ACCOUNTDISABLE
flag from the account in AD.
To set a user password in Active Directory you can simply map the column that contains your passwords to the DS-SetPassword
field in the target.
DS-
columns are Data Sync attribute columns that handle the addition of that field for each user. In previous versions you would have needed to write Project Automation code to update the password field. Now Data Sync does it for you.
By default, Data Sync will also set the status in AD so that the user must update their password when they next logon.
If you do not want users to change the password, then you will need to set OnCreateChangePasswordNextLogon to False
. To do this go to the connection property window for AD and change the value for OnCreateChangePasswordNextLogon
.
Note: Passwords cannot be updated for existing users with this method. You will need to use Project Automation to do this.
To update the password for existing users you will need to add a few lines of code to Project Automation Item Events.
Project Automation allows you to run your own .NET C# code at certain points in the Data Sync process.
You can open and enable Project Automation by going to View
> Project Automation Window
. Then click Enable Project Automation
to get started.
This will then open the code view where we can write the code we need.
If you are getting the password value from your source data you need to map this column to the DS-SetPassword
column from the target.
You also need to edit the schema properties, setting the Data Compare property Ignore
to True
, so that the password field does not always trigger update events.
As defining a password for users will not be very secure you will want users to have to change their password when they login, this has been set in the code below using pwdLastSet
.
Your Project Automation code should look similar to:
public override void AfterUpdateItem(object sender, DataCompareItemInvariant item, object identity)
{
Trace.WriteLine("AfterUpdate->{0}", identity);
var values = item.ToAddItemDictionary(TargetMapping); //Gets column names from the target
using(var entry = DataSourceB.GetDirectoryEntry((string)identity))
{
var uac = (int)entry.Properties["userAccountControl"].Value;
uac = uac & ~0x2; //Unlocked
entry.Properties["userAccountControl"].Value = uac; //Set the UAC to unlocked
entry.Invoke("SetPassword", values["DS-SetPassword"]); //Set the password
entry.Properties["pwdLastSet"].Value = 0; //Set user must change password at next logon
entry.CommitChanges();
}
}
If you want to supply a hard-coded default password, then you do not need to add the password columns to the schema map and you can use code similar to the following:
public override void AfterUpdateItem(object sender, DataCompareItemInvariant item, object identity)
{
Trace.WriteLine("AfterUpdate->{0}", identity);
using(var entry = DataSourceB.GetDirectoryEntry((string)identity))
{
var uac = (int)entry.Properties["userAccountControl"].Value;
uac = uac & ~0x2; //Unlocked
entry.Properties["userAccountControl"].Value = uac; //Set the UAC to unlocked
entry.Invoke("SetPassword", "!password123"); //Set the default password
entry.Properties["pwdLastSet"].Value = 0; //Set user must change password at next logon
entry.CommitChanges();
}
}