【发布时间】:2018-11-06 00:28:17
【问题描述】:
我正在尝试以编程方式更改多个用户的密码,特别是不使用 System.DirectoryServices.AccountManagement (PrincipalContext) 我有这段工作代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices;
namespace ADScriptService.core
{
class ExportTool
{
const AuthenticationTypes = AuthenticationTypes.Secure | AuthenticationTypes.Sealing | AuthenticationTypes.ServerBind;
private static DirectoryEntry directoryEntry = new DirectoryEntry(ADScriptService.Properties.Settings.Default.ActiveDirectoryPath, ADScriptService.Properties.Settings.Default.ServerAdminUser, ADScriptService.Properties.Settings.Default.ServerAdminPwd, AuthenticationTypes.Secure);
private static DirectorySearcher search = new DirectorySearcher(directoryEntry);
public void Export()
{
string path = ADScriptService.Properties.Settings.Default.ActiveDirectoryPath;
string adminUser = ADScriptService.Properties.Settings.Default.ServerAdminUser;
string adminPassword = ADScriptService.Properties.Settings.Default.ServerAdminPwd;
string userName = "exampleUser";
string newPassword = "P455w0rd";
try
{
search.Filter = String.Format("sAMAccountName={0}", userName);
search.SearchScope = SearchScope.Subtree;
search.CacheResults = false;
SearchResult searchResult = search.FindOne();
if (searchResult == null) Console.WriteLine("User Not Found In This Domain");
DirectoryEntry userEntry = searchResult.GetDirectoryEntry();
userEntry.Path = userEntry.Path.Replace(":389", "");
Console.WriteLine(String.Format("sAMAccountName={0}, User={1}, path={2}", userEntry.Properties["sAMAccountName"].Value, userEntry.Username, userEntry.Path));
userEntry.Invoke("SetPassword", new object[] { newPassword });
userEntry.Properties["userAccountControl"].Value = 0x0200 | 0x10000;
userEntry.CommitChanges();
Console.WriteLine("Se ha cambiado la contraseña");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
这是一个使用单个用户的示例,但我的程序应该做的是遍历约 120k 用户。
但是,设置搜索过滤器、查找一个结果并获取 DirectoryEntry 的操作每个用户大约需要 2 或 3 秒,因此我尝试使用 DirectoryEntry.Children 属性给出的 DirectoryEntries 结构,这意味着替换后面的六行“尝试{”只需 DirectoryEntry userentry = directoryEntry.Children.Find("CN=" + userName);
所以示例代码如下所示:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices;
namespace ADScriptService.core
{
class ExportTool
{
const AuthenticationTypes = AuthenticationTypes.Secure | AuthenticationTypes.Sealing | AuthenticationTypes.ServerBind;
private static DirectoryEntry directoryEntry = new DirectoryEntry(ADScriptService.Properties.Settings.Default.ActiveDirectoryPath, ADScriptService.Properties.Settings.Default.ServerAdminUser, ADScriptService.Properties.Settings.Default.ServerAdminPwd, AuthenticationTypes.Secure);
private static DirectorySearcher search = new DirectorySearcher(directoryEntry);
public void Export()
{
string path = ADScriptService.Properties.Settings.Default.ActiveDirectoryPath;
string adminUser = ADScriptService.Properties.Settings.Default.ServerAdminUser;
string adminPassword = ADScriptService.Properties.Settings.Default.ServerAdminPwd;
string userName = "exampleUser";
string newPassword = "P455w0rd";
try
{
DirectoryEntry userEntry = directoryEntry.Children.Find("CN=" + userName);
userEntry.Path = userEntry.Path.Replace(":389", "");
Console.WriteLine(String.Format("sAMAccountName={0}, User={1}, path={2}", userEntry.Properties["sAMAccountName"].Value, userEntry.Username, userEntry.Path));
userEntry.Invoke("SetPassword", new object[] { newPassword });
userEntry.Properties["userAccountControl"].Value = 0x0200 | 0x10000;
userEntry.CommitChanges();
Console.WriteLine("Se ha cambiado la contraseña");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
但此代码在调用行(userEntry.Invoke("SetPassword", new object[] { newPassword }); 中出现以下错误:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: The RPC server is unavailable. (Excepción de HRESULT: 0x800706BA)
英文表示RCP服务器不可用。我在这里被困了几天,我只发现这可能是因为一些身份验证问题。
调用“组”方法有效(userEntry.Invoke("Groups");),管理员,即我登录到 ActiveDirectory 的用户,拥有所有权限。此外,密码策略是完全宽松的,没有最小长度或复杂性。
同样,因为程序必须遍历,所以真正的程序实际上会遍历 DirectoryEntry 的子项:
foreach(DirectoryEntry child in directoryEntry.Children)
{
child.Invoke("SetPassword", new object[] { newPassword });
child.CommitChanges();
}
非常感谢!
【问题讨论】:
-
请将异常信息翻译成英文...
-
完成,我已经翻译好了
标签: c# .net active-directory directoryservices