开发者

Ways to fetch domain username from SID string in VBScript

Recently I was working on a system administration script in pure VBScript where the requirements are that it must be portable with no additional software installation needed.

I have the string version of the SID (e.g. "S开发者_运维知识库-1-5-21-123456789...") and want to get the username and domain name.

Attempts to do this via WMI fail in part because of the 10,000's of objects it has to search through on the domain controllers.

But perhaps it can be done one of these ways:

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

  2. if we can assume that the .NETfx 2.0 is installed (which I would really prefer to avoid, since it will not be totally portable), via the System.Security.Principal (example in C#: using System.Security.Principal; string account = new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString();)

Any suggestions for me?


Building group membership in multidomain forest.

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


You can simply bind with ADSI to the SID. In VBScript that would be something like this:

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


The best method I have found on my own is querying WMI, like this:

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

As you can see I had to add some error handli--er, rather--"skipping blindly over errors", because the query doesn't always succeed (and there could be a handful of potential causes that aren't easy to test for).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜