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

发布于 2024-12-05 03:06:58 字数 769 浏览 1 评论 0原文

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

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

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

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

  1. via p/invoke from ADVAPI32.DLL的LookupAccountSid函数

  2. if 我们可以假设 .NETfx 2.0 已安装(我真的希望避免这种情况,因为它不完全可移植),通过 System.Security.Principal (C# 中的示例:using System.Security.Principal; string account = new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString();)

对我有什么建议吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

场罚期间 2024-12-12 03:06:58

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

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

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
青瓷清茶倾城歌 2024-12-12 03:06:58

您可以简单地使用 ADSI 绑定到 SID。在 VBScript 中,会是这样的:

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

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-...>")
Smile简单爱 2024-12-12 03:06:58

我自己找到的最好方法是查询 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

如您所见,我必须添加一些错误处理程序——呃,而不是——“盲目地跳过错误”,因为查询并不总是成功(并且可能存在一些不易测试的潜在原因)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文