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時間ぐらいはまった…。