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:
via p/invoke from ADVAPI32.DLL's LookupAccountSid function
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).
精彩评论