管理者パスワードをコードに記述せず、外部のテキストファイルを読み出して使用します。
外部テキストファイルは 12行目に指定しています。
Windows Server 2012 R2 + IIS 8.5 で正常動作を確認しましたが、IISのバージョンによってはスクリプトより上位のフォルダーを参照できないので、その際は適宜ファイルの場所を移動してください。
pwdchange2.aspx
<%@ PAGE LANGUAGE="C#" %> <%@ Assembly Name="System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %> <%@ Assembly Name="System.DirectoryServices.AccountManagement, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" %> <%@ Import Namespace="System.DirectoryServices" %> <%@ Import Namespace="System.DirectoryServices.AccountManagement" %> <%@ Import Namespace="System.IO" %> <html> <head> <title>AD User Change Password</title> <script runat="server"> bool debugMode = false; string passwordFilePath = @"C:\test.pwd"; void Page_Load(object sender, EventArgs e) { if(debugMode){ lbl_debug.Text = "Debug Mode: ON"; } old_password.TextMode = TextBoxMode.Password; new_password.TextMode = TextBoxMode.Password; new_password2.TextMode = TextBoxMode.Password; } void password_change(object sender, EventArgs e) { String ldapBaseDN = ""; String dNSDomainName = ""; String nTDomainName = ""; String samName = ""; String userName = user_name.Text; String searchText = ""; String ldapUserPath = ""; lbl_change_result.Text = ""; lbl_system_result.Text = ""; lbl_base_dn.Text = ""; lbl_dns_domain.Text = ""; lbl_nt_domain.Text = ""; lbl_user_path.Text = ""; lbl_sam.Text = ""; if(userName.Length == 0){ lbl_system_result.Text = "ユーザー名が指定されていません。"; return; } if(String.Compare(new_password.Text, new_password2.Text) != 0){ lbl_system_result.Text = "新しいパスワードが一致していません。"; return; } try { DirectoryEntry domain = new DirectoryEntry("LDAP://RootDSE"); ldapBaseDN = domain.Properties["defaultNamingContext"][0].ToString(); if(debugMode){ lbl_base_dn.Text = " LDAP Base DN: " + ldapBaseDN; } } catch(Exception ex1) { if(debugMode){ lbl_system_result.Text = ex1.Message; }else{ lbl_system_result.Text = "このサーバーはドメインに参加していないようです。"; } return; } System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex("=([^,]+),?"); System.Text.RegularExpressions.Match m = r.Match(ldapBaseDN); if (m.Success) { dNSDomainName = m.Groups[1].ToString(); m = m.NextMatch(); while (m.Success) { dNSDomainName = dNSDomainName + "." + m.Groups[1].ToString(); m = m.NextMatch(); } } if(debugMode){ lbl_dns_domain.Text = " DNS Domain: " + dNSDomainName; } nTDomainName = Environment.GetEnvironmentVariable("USERDOMAIN"); if(debugMode){ lbl_nt_domain.Text = " NT Domain: " + nTDomainName; } searchText = "(&(objectClass=user)(!objectClass=computer)(|(sAMAccountName=" + userName + ")(cn=" + userName + ")))"; try { using (DirectorySearcher ds = new DirectorySearcher(searchText)) { SearchResult sr = ds.FindOne(); if(sr == null) { if(debugMode){ lbl_system_result.Text = "ユーザー名が見つかりません。"; } else { lbl_system_result.Text = "ユーザー名またはパスワードが違います。"; } return; } else { ldapUserPath = sr.Path; if(debugMode){ lbl_user_path.Text = " LDAP User Path: " + ldapUserPath; } samName = sr.Properties["sAMAccountName"][0].ToString(); if(debugMode){ lbl_sam.Text = " sAMAccountName: " + samName; } } } } catch(ArgumentException ae) { lbl_system_result.Text = ae.Message; return; } try { string adminName = ""; string adminPass = ""; using(StreamReader sr = File.OpenText(passwordFilePath)) { adminName = sr.ReadLine(); adminPass = sr.ReadLine(); if(debugMode){ lbl_admin_name.Text = adminName; lbl_admin_pass.Text = adminPass; } } using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain, dNSDomainName, adminName, adminPass)) using(UserPrincipal usr = UserPrincipal.FindByIdentity(ctx, samName)) { usr.ChangePassword(old_password.Text, new_password.Text); if(debugMode){ lbl_change_result.Text = "パスワードを変更しました。"; } else{ Response.ClearContent(); Response.Write("<html><head></head><body>パスワードを変更しました。</body></html>"); Response.Flush(); Response.Close(); } } } catch(PasswordException pe) { if(debugMode){ lbl_system_result.Text = "PE:" + pe.Message; } else{ lbl_system_result.Text = "ユーザー名またはパスワードが違います。"; } return; } catch(Exception ex2) { if(debugMode){ lbl_system_result.Text = "EX:" + ex2.Message; } else { lbl_system_result.Text = "ユーザー名またはパスワードが違います。"; } return; } } </script> </head> <body> <form runat="server"> <table> <tr><td>ユーザー名</td><td><asp:TextBox id="user_name" Columns="50" Rows="1" Text="" runat="server" /></td></tr> <tr><td>現在のパスワード</td><td><asp:TextBox id="old_password" Columns="50" Rows="1" Text="" runat="server" /></td></tr> <tr><td>新しいパスワード</td><td><asp:TextBox id="new_password" Columns="50" Rows="1" Text="" runat="server" /></td></tr> <tr><td>確認入力</td><td><asp:TextBox id="new_password2" Columns="50" Rows="1" Text="" runat="server" /></td></tr> </table> <asp:Button id="btn_change" Text="Change" OnClick="password_change" runat="server" /> <asp:Label style="color:#080;font-weight:bold;margin-left:1em" id="lbl_change_result" Text="" runat="server" /> <asp:Label style="color:#f00;font-weight:bold;margin-left:1em" id="lbl_system_result" Text="" runat="server" /> <!-- ここから下はデバッグ情報 --> <asp:Label id="lbl_debug" Text="" runat="server" /> <asp:Label id="lbl_base_dn" Text="" runat="server" /> <asp:Label id="lbl_nt_domain" Text="" runat="server" /> <asp:Label id="lbl_dns_domain" Text="" runat="server" /> <asp:Label id="lbl_user_path" Text="" runat="server" /> <asp:Label id="lbl_sam" Text="" runat="server" /> <asp:Label id="lbl_admin_name" Text="" runat="server" /> <asp:Label id="lbl_admin_pass" Text="" runat="server" /> </form> </body> </html>