如何从ActiveDirectory

时间:2017-10-13 06:38:28

标签: vb.net active-directory

我正在尝试从ActiveDirectory读取管理员密码的过期时间

Dim DC = New  PrincipalContext(ContextType.Domain)
Dim cmp = ComputerPrincipal.FindByIdentity(DC, hostnm)
Dim desting As String = cmp.DistinguishedName
Dim de As New DirectoryEntry("LDAP://" & desting)
pwdexp = de.Properties("ms-Mcs-AdmPwdExpirationTime").Value.ToString()

但我看到的只是<COM Type>enter image description here

但是, PowerShell 可以轻松读取管理员密码的过期时间

$TestValue = [adsi]"LDAP://CN=xxx,OU=xxx,OU=xxx,OU=xxx,OU=xxx,DC=xxx,DC=xxx,DC=xx"
$TestValue.ConvertLargeIntegerToInt64($Testvalue."ms-Mcs-AdmPwdExpirationTime"[0])

我知道有这样的财产: enter image description here

有趣的是,我可以阅读另一个参数ms-Mcs-AdmPwd

Dim DC = New  PrincipalContext(ContextType.Domain)
Dim cmp = ComputerPrincipal.FindByIdentity(DC, hostnm)
Dim desting As String = cmp.DistinguishedName
Dim de As New DirectoryEntry("LDAP://" & desting)
pwdexp = de.Properties("ms-Mcs-AdmPwdExpirationTime").Value.ToString()
从调试器中可以看到

和值:

enter image description here

如何正确阅读属性ms-Mcs-AdmPwdExpirationTime

1 个答案:

答案 0 :(得分:2)

返回值是DateTime,在AD中表示为LargeInteger。您必须将其转换为能够阅读它。

请注意,在PowerShell中,您使用ConvertLargeIntegerToInt64转换值。所以,我们也需要先做同样的事情。

C#中的代码

            /// <summary>
            /// Decodes IADsLargeInteger objects into a FileTime format (long)
            /// </summary>
            public static long ConvertLargeIntegerToLong(object largeInteger)
            {
                var type = largeInteger.GetType();
                var highPart = (int)type.InvokeMember("HighPart", BindingFlags.GetProperty, null, largeInteger, null);
                var lowPart = (int)type.InvokeMember("LowPart", BindingFlags.GetProperty, null, largeInteger, null);

                return (long)highPart << 32 | (uint)lowPart;
            }

并在VB.NET中(使用http://converter.telerik.com/

''' <summary>
''' Decodes IADsLargeInteger objects into a FileTime format (long)
''' </summary>
Public Shared Function ConvertLargeIntegerToLong(largeInteger As Object) As Long
    Dim type = largeInteger.[GetType]()
    Dim highPart = CInt(type.InvokeMember("HighPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))
    Dim lowPart = CInt(type.InvokeMember("LowPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))

    Return CLng(highPart) << 32 Or CUInt(lowPart)
End Function

然后使用下面的

读取日期值
var pwdExpTime = DateTime.FromFileTime(ConvertLargeIntegerToLong(de.Properties["ms-Mcs-AdmPwdExpirationTime"].Value));

和VB.NET中的

Dim pwdExpTime = DateTime.FromFileTime(ConvertLargeIntegerToLong(de.Properties("ms-Mcs-AdmPwdExpirationTime").Value))