System.DirectoryServices.AccountManagement を使用して、Active Directoryにユーザーを追加する処理をしていました。
using (var principalContext = new PrincipalContext(ContextType.Domain, host, ou, AdUser, AdPassword))
{
using (var userprincipal = new UserPrincipalGloops(principalContext))
{
if (!string.IsNullOrEmpty(lastName))
{
userprincipal.GivenName = familiyName;
}
if (!string.IsNullOrEmpty(familiyName))
{
userprincipal.Surname = familiyName;
}
if (!string.IsNullOrEmpty(roma))
{
userprincipal.Name = roma;
}
if (!string.IsNullOrEmpty(familiyName) && !string.IsNullOrEmpty(lastName))
{
userprincipal.DisplayName = String.Format("{0} {1}", familiyName, lastName);
}
if (!string.IsNullOrEmpty(mail))
{
userprincipal.EmailAddress = mail;
}
if (!string.IsNullOrEmpty(employeeNumber))
{
userprincipal.EmployeeNumber = employeeNumber;
}
if (!string.IsNullOrEmpty(idm))
{
userprincipal.Description = idm;
}
if (!string.IsNullOrEmpty(idm))
{
userprincipal.SamAccountName = account;
}
userprincipal.SetPassword(password);
userprincipal.Enabled = true;
userprincipal.PasswordNeverExpires = true;
userprincipal.UserCannotChangePassword = true;
try
{
userprincipal.Save();
}
catch (Exception ex)
{
Logger.Warn("[Create Ad Account] " + ex.Message, ex);
return string.Format("NoCreate:{0}",ex.Message);
}
}
}userprincipa.save()で、例外が発生して、「サーバーがプロセスを実行しようとしません。」と言われちゃいます。(いやいや、実行しろよ!と突っ込みたくなったり)
今回、employee numberに情報を格納するために、プリンシパルの拡張をしていました。
MSDNのサンプルでは、プリンシパルの拡張の冒頭が次のようになっていました。
なので、あまり深く考えずにコピペしたのが運の尽き。
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("inetOrgPerson")]
public class InetOrgPerson : UserPrincipal
{「DirectoryObjectClass」が拡張するクラス名を入れておけば良さそうに見えます。実際、それでも既存ユーザーの更新では問題なく動作するように見えます。
しかし、ユーザーの新規作成時には動作しません。
userを指定すると、例外が発生せずにユーザーを新規作成できるようになりました。
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("user")]
public class UserPrincipalGloops: UserPrincipal
{2時間ぐらいはまった…。