使用DirectoryEntry.Invoke(“SetPassword”,...)设置初始AD帐户密码,我得到“RPC服务器不可用”错误

时间:2012-11-16 06:21:16

标签: vb.net active-directory directoryservices userprincipal

我正在工作的公司有一个网络服务,可以根据输入的信息创建新的Active Directory帐户,例如用户名,名字,姓氏,OU1,OU2等

此Web服务在Windows Server 2003上运行良好。现在我正在努力将Web服务移动到2008 R2服务器。但是,某个功能不再起作用,即它尝试为新创建的帐户设置随机初始密码。

抛出的异常是一个TargetInvocationException,它包含一个COMException的内部异常,消息为“RPC服务器不可用”。

Imports System.DirectoryServices

Dim ldapPath As String = "..." 'assume valid LDAP path
Dim objContainer As DirectoryEntry = New DirectoryEntry(ldapPath, vbNullString, vbNullString, AuthenticationTypes.Secure)
objUser = objContainer.Children.Add("cn=" & Username.Trim, "user")

'sets objUser.Properties e.g. givenName, displayName, userPrincipalName, samAccountName, etc. Not important...
objUser.CommitChanges()

strPassword = RandomPassword()  'function that generates random password
objUser.Invoke("SetPassword", New Object() {strPassword})

objUser.Properties("useraccountcontrol").Value = "512" ' set as normal account
objUser.CommitChanges()

'and so on...

错误发生在说: objUser.Invoke(“SetPassword”,New Object(){strPassword})

奇怪的是帐户创建本身有效,我可以从Active Directory用户和计算机中看到新用户。 我咨询了一些管理DC和Web服务器安全性的不同人员,他们真的不知道为什么......

最后,我想出了一种不同的设置密码的方法,即使用System.DirectoryServices.AccountManagement库。

所以代码就像这样:

Imports System.DirectoryServices
Imports System.DirectoryServices.AccountManagement

Dim ldapPath As String = "..." 'assume valid LDAP path
Dim objContainer As DirectoryEntry = New DirectoryEntry(ldapPath, vbNullString, vbNullString, AuthenticationTypes.Secure)
Dim objUser As DirectoryEntry = objContainer.Children.Add("cn=" & Username.Trim, "user")

'sets objUser.Properties e.g. givenName, displayName, userPrincipalName, samAccountName, etc. Not important...
objUser.CommitChanges()

Dim domainContext As PrincipalContext = New PrincipalContext(ContextType.Domain, ...)
Dim user As UserPrincipal = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, Trim(Username))

strPassword = RandomPassword()  'function that generates random password
user.SetPassword(strPassword)

user.Enabled = True                 'setting these two properties
user.PasswordNotRequired = False    'result in useraccountcontrol value = 512 (normal account)
user.Save()

'and so on...

我正在将旧代码与新代码混合在一起,但它似乎在新服务器上运行得非常好。需要注意的一点是,有时UserPrincipal.FindByIdentity调用最初会返回Nothing,我相信由于帐户创建或复制的延迟。所以我必须通过多次尝试FindByIdentity来确保用户对象不是Nothing,直到我得到对象。

尽管找到了解决这个问题的解决方案(更像是一种解决方法),但我仍然很困惑为什么旧代码在新服务器上不起作用,但新代码却不行。这个错误非常普遍,在互联网上寻找线索只会导致更多的混乱。

非常感谢那里的专家是否会对我的新代码的外观,任何问题发表一些看法或评论?

提前致谢。

0 个答案:

没有答案