从VBScript中的SID字符串获取域用户名的方法

时间:2011-09-15 19:12:01

标签: vbscript active-directory

最近我在使用纯VBScript编写系统管理脚本,其要求是必须是可移植的,无需额外的软件安装。

我有SID的字符串版本(例如“S-1-5-21-123456789 ...”),想要获取用户名和域名。

尝试通过WMI执行此操作失败的部分原因是它必须在域控制器上搜索10,000个对象。

但也许可以通过以下方式之一完成:

  1. via p/invoke from ADVAPI32.DLL's LookupAccountSid function

  2. if 我们可以假设安装了.NETfx 2.0(我真的更愿意避免,因为它不是完全可移植的),via the System.Security.Principal(例如C#:using System.Security.Principal; string account = new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString();

  3. 对我有什么建议吗?

3 个答案:

答案 0 :(得分:1)

在多域林中构建组成员身份。

Const ADS_SCOPE_ONELEVEL = 1
Const ADS_SCOPE_SUBTREE = 2

Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand =   CreateObject("ADODB.Command")
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
Set objRootLDAP = GetObject("LDAP://RootDSE")

objCommand.CommandText = "<LDAP://`your domain A DC full name here`" & ">;(&(objectCategory=group)(name=" & `group name` & ")); samAccountName,distinguishedname,name;subtree"
               objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set oGroup = objCommand.Execute

DGroupName = oGroup.Fields("distinguishedname")
Set objGroup = GetObject("LDAP://" & DGroupName)

For Each obj In objGroup.Members
    i = i + 1

    If left(obj.cn,9)="S-1-5-21-" Then
        objCommand.CommandText = "<LDAP://`your domain B DC full name here`" & ">;(&(objectCategory=person)(objectSID=" & obj.cn & ")); samAccountName,distinguishedname,name;subtree"
               objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
        Set exUser = objCommand.Execute

        exUserAttribute1 = exUser.Fields("sAMAccountName")
        exUserAttribute2 = exUser.Fields("name")
    Else
        UserAttribute1 = obj.sAMAccountName
        UserAttribute1 = obj.cn
    End if

答案 1 :(得分:0)

您只需将ADSI绑定到SID即可。在VBScript中会是这样的:

Dim myUser
Set myUser = GetObject("LDAP://<SID=S-1-5-21-...>")

答案 2 :(得分:0)

我自己找到的最好的方法是查询WMI,如下所示:

Sub GetUserFromSID(BYVAL strSID, BYREF strUserName, BYREF strDomainName)
    'given the SID in string/SDDL form, fetch the user and domain names
    'this method should work for local and parent AD domain users (i.e. direct trust)
    '...but it probably won't work for remote domains over transitive trusts
    On Error Resume Next
    Dim objSID : Set objSID = objWMI.Get("Win32_SID='" & strSID & "'")
    strUserName = objSID.AccountName
    strDomainName = objSID.ReferencedDomainName
    On Error Goto 0
    If strDomainName = "NT AUTHORITY" Then strDomainName = GetHostname() 'so it matches active user queries
End Sub

正如你所看到的,我不得不添加一些错误,而是 - “盲目地跳过错误”,因为查询并不总是成功(并且可能有少数潜在的原因不是易于测试)。