Hi everyone-
Hopefully this is an easy one...
I'm trying to detect the status of an Active Directory user's account (disabled, password expired, locked, etc). No matter what the user's account is actually set to, it always returns that the account is normal (512, or ADS_UF_NORMAL_ACCOUNT), even though I expect a different value.
Can anyone see what I'm doing wrong so I always get 512 returned from the user's UserAccountControl property?
Thanks in advance...
Hopefully this is an easy one...
I'm trying to detect the status of an Active Directory user's account (disabled, password expired, locked, etc). No matter what the user's account is actually set to, it always returns that the account is normal (512, or ADS_UF_NORMAL_ACCOUNT), even though I expect a different value.
Can anyone see what I'm doing wrong so I always get 512 returned from the user's UserAccountControl property?
Thanks in advance...
VB.NET:
Public Shared Function CheckAccountStatus(ByVal username As String) As String
Dim rootDN As String
Dim rootDSE As DirectoryEntry
Dim searchRoot As DirectoryEntry
Dim userEntry As DirectoryEntry
Dim searcher As DirectorySearcher
Dim results As SearchResultCollection
Dim result As SearchResult
Try
'note the authenicationtypes here
'you need to either use SecureSocketsLayer or Kerberos (Secure + Sealing)
rootDSE = New DirectoryEntry(String.Format("LDAP://{0}/rootDSE", _dcDNS), _ADServiceAccountName, _ADServiceAccountPassword, AuthenticationTypes.Secure Or AuthenticationTypes.Sealing Or AuthenticationTypes.ServerBind)
rootDN = DirectCast(rootDSE.Properties("defaultNamingContext").Value, String)
searchRoot = New DirectoryEntry(String.Format("LDAP://{0}/{1}", _dcDNS, rootDN), _ADServiceAccountName, _ADServiceAccountPassword, AuthenticationTypes.Secure Or AuthenticationTypes.Sealing Or AuthenticationTypes.ServerBind)
searcher = New DirectorySearcher(searchRoot)
searcher.Filter = String.Format("sAMAccountName={0}", username)
searcher.SearchScope = SearchScope.Subtree
searcher.CacheResults = False
'I use FindAll here because FindOne leaks memory if it does not find anything
'in .NET 1.0 and 1.1
results = searcher.FindAll()
For Each result In results
'only use this method on .NET 1.1 or higher
'otherwise, get the adsPath value and build a new
'DirectoryEntry with the supplied credentials
userEntry = result.GetDirectoryEntry()
Exit For 'this is redundant because sAMAccountName is unique in the [url="http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21123504.html#"]domain[/url], but it is done for clarity
Next
If userEntry Is Nothing Then
Return "User not found in this domain."
End If
Dim firstName, lastName As String
Dim DisplayName As String = GetDisplayName(username, firstName, lastName)
Dim strResult As String = String.Empty
Dim strCallHelp As String = " - Please contact the Help Desk at xHELP (x4357) for assistance."
Select Case userEntry.Properties("userAccountControl").Value
Case ADS_USER_FLAG.ADS_UF_ACCOUNTDISABLE
strResult = "Account disabled" & strCallHelp
Case ADS_USER_FLAG.ADS_UF_LOCKOUT
strResult = "Locked" & strCallHelp
Case ADS_USER_FLAG.ADS_UF_NORMAL_ACCOUNT ' <-- always hits this, even when I disable an account
strResult = "OK"
Case ADS_USER_FLAG.ADS_UF_PASSWORD_EXPIRED
strResult = "Expired password. Please use the form below to set your new password."
Case Else
strResult = userEntry.Properties("userAccountControl").Value.ToString & strCallHelp
End Select
Return userEntry.Properties("userAccountControl").Value.ToString ' <-- always returns 512
Catch ex As System.Reflection.TargetInvocationException
Return ex.innerexception.tostring
Catch ex As Exception
Return ex.InnerException.tostring
Finally 'these prevent other memory leaks
If Not userEntry Is Nothing Then userEntry.Dispose()
If Not results Is Nothing Then results.Dispose()
If Not searcher Is Nothing Then searcher.Dispose()
If Not searchRoot Is Nothing Then searchRoot.Dispose()
If Not rootDSE Is Nothing Then rootDSE.Dispose()
End Try
End Function