1

私が働いている会社には、ユーザー名、名、姓、OU1、OU2 などの入力情報に基づいて新しい Active Directory アカウントを作成できる Web サービスがあります。

この Web サービスは、Windows Server 2003 で正常に動作しています。現在、Web サービスを 2008 R2 サーバーに移行する作業を行っています。ただし、新しく作成されたアカウントにランダムな初期パスワードを設定しようとすると、特定の機能が機能しなくなります。

スローされる例外は、「RPC サーバーを利用できません」というメッセージを含む COMException の内部例外を含む TargetInvocationException です。

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...

これには古いコードと新しいコードが混在していますが、新しいサーバーではうまく機能しているようです。注意すべきことの 1 つは、UserPrincipal.FindByIdentity 呼び出しが最初に Nothing を返す場合があることです。これは、アカウントの作成またはレプリケーションの遅延が原因であると考えられます。そのため、オブジェクトを取得するまで FindByIdentity を複数回試行して、ユーザー オブジェクトが Nothing でないことを確認する必要があります。

問題の解決策 (回避方法のようなもの) を見つけたにもかかわらず、古いコードが新しいサーバーでは機能しないのに、新しいサーバーでは機能する理由についてまだ混乱しています。エラーは非常に一般的なものであり、インターネットで手がかりを検索すると、混乱が生じるだけです。

そこの専門家がいくつかの光を当てるか、私の新しいコードがどのように見えるかについてコメントすることさえできれば、本当に感謝します。問題はありますか?

前もって感謝します。

4

0 に答える 0