使用 SID 从 Active Directory 检索用户详细信息

使用 SID 从 Active Directory 检索用户详细信息

当我有某个用户的 SID 时,如何才能在我的 AD 中找到该用户。我不想依赖其他属性,因为我正在尝试检测这些属性的更改。示例:我收到一条有关用户记录更改的消息,其中包含:

Message: User Account Changed:

    Target Account Name:    test12

    Target Domain:  DOMAIN

    Target Account ID:  %{S-1-5-21-3968247570-3627839482-368725868-1110}

    Caller User Name:   Administrator

    Caller Domain:  DOMAIN

    Caller Logon ID:    (0x0,0x62AB1)

    Privileges: -

我想通知用户有关更改。因此我需要来自 AD 的帐户信息。

答案1

启动 Windows PowerShell 并运行:

$strSID="S-1-5-21-500000003-1000000000-1000000003-1001"
$uSid = [ADSI]"LDAP://<SID=$strSID>"
echo $uSid

输出应该是这样的,

distinguishedName : {CN=John Doe,OU=Domain Admins,OU=People,OU=xxx,DC=xxx}
Path              : LDAP://<SID=S-1-5-21-500000003-1000000000-1000000003-1001>

答案2

执行此操作的“LDAP 方式”是使用 GUID(或 SID)检索基本对象,这将仅检索基本对象,而不附加其他类数据。但是,从此基本对象中,您可以检索用户对象的实际“distinguishedName”。使用“distinguishedName”属性检索用户对象将返回具有完整类数据的 DirectoryEntry 对象 (.Net/C#/PowerShell) 或 iadsUser 对象 (VBScript),并允许您获取所需的任何其他属性数据。

问题在于使用 GUID(或 SID)检索初始对象。有些资料说,您必须将字符串格式 GUID(即 {28c67c50-9778-47a4-a77a-bf56f238a0c4})转换为字节数组的字符串表示形式(即“\50\7c\c6\28\78\97\a4\47\7a\a7\bf\56\f2\38\a0\c4”)才能传递给 LDAP。根据Microsoft 文档事实并非如此。GUID/SID 的简单字符串表示就足够了。

以下是如何通过 GUID 绑定到对象然后检索具有完整类数据的实际用户对象的示例。如果您使用 GUID 进行绑定,Powershell 实际上会提取完整的对象。如果您使用 VBScript,则需要执行两步过程。

另外,请注意,虽然 Microsoft 文档说多种 GUID 字符串格式是可以接受的,但我能够成功使用的唯一格式是删除 {}- 字符。 ,请注意这是不是一个正确的“字节数组”字符串,但只是去掉了特殊字符的 GUID 字符串。

$strGUID = "{28c67c50-9778-47a4-a77a-bf56f238a0c4}" -replace '-|{|}',''
$guid = [ADSI]"LDAP://<GUID=$strGUID>"
$user = [ADSI]$guid.distinguishedName

相同的过程可用于 SID 绑定。描述此内容的 MSDN 页面表示有几种可用的 fstring 格式,但最常见的是 S-1-5-...-...-...-... 格式。

#Powershell
$strSID="S-1-5-21-500000003-1000000000-1000000003-1001"
$uSid = [ADSI]"LDAP://<SID=$strSid>"
$user = [ADSI]$user.distinguishedName

*** 查询 ***

如果您要执行 LDAP 查询来查找对象(例如,通过将“objectGUID”与字节数组进行比较或将“objectSID”与字节数组进行比较),则需要进行“正确”的字节数组转换。需要注意的是,字节数组的顺序与字符串表示不同,因为对于 GUID,它存储为 DWORD-WORD-WORD-WORD-BYTES,并且确实考虑了字节顺序。将字节数组转换为 SID 具有类似的条件。

有几种不同的方法可以完成转换,Technet 有一个简单的 vbScript 算法。您还可以使用 System.Guid 通过 C#/VB.Net 做一些更有趣的事情,或者通过 PowerShell 中的简单脚本(一定会喜欢 PowerShell!):

#Powershell
#   Creates a new System.GUID object from the supplied string.
#   Only need for this example.
$guid = [system.guid]"{28c67c50-9778-47a4-a77a-bf56f238a0c4}" 
$out=""
#Formats the array of integers as a backslash-delimited string of Hex values
$guid.ToByteArray() | %{ $out += $("\{0:x2}" -f $_) }

然后您应该能够使用标准 LDAP 过滤器查询该对象:

(&(objectClass=User)(objectGUID=\50\7c\c6\28\78\97\a4\47\a7\7a\bf\56\f2\38\a0\c4))

...或者您可能要查询的其他内容。这也适用于 SID。

答案3

好的。我找到了一种通过 Active Directory 执行此操作的方法。为了完整起见,以下是代码:

REM Converts the SID into a format, that can be processed by ADSI or WMI
Function NormalizeSid(strSidToNormalize)
  Dim regEx,strReplace
  strReplace=""
  ' Create regular expression.
  Set regEx = New RegExp
  regEx.Global  = True
  regEx.Pattern = "(%|{|})"
  regEx.IgnoreCase = True

  ' Make replacement.
  NormalizeSid = regEx.Replace(strSidToNormalize, strReplace)
End Function

REM Searches for a SID the in the Message that was passed as argument
REM SID returned will be of the  form %{S-1-5-21-3968247570-3627839482-368725868-1110}
REM NOTE: Neither WMI nor ADSI will accept this. Use NormalizeSid like in FindUser
Function FindSidInMessage(Message)
    Dim strAccountRegex
    Dim objRegex
    Dim objMatch
    Dim strSID

    strAccountRegex = "(\%\{S\-[,0-9,\-]*\})"
    Set objRegex    = new RegExp
    objRegex.Pattern= strAccountRegex

    for each objMatch in objRegex.Execute(Message)
            REM Wscript.StdOut.writeLine "Found an Account ID: " & objMatch.value
            strSID=objMatch.value
    next

    FindSidInMessage=strSID
End Function 

REM Searches Directory for the User matching the SID passed as parameter
Function FindUser(userSID)
    Dim normalizedSID
    Dim objUser

    normalizedSID=NormalizeSid(userSID)
    Wscript.Echo "SID after escaping: " & normalizedSID

    Wscript.StdOut.writeLine "Querying AD to retrieve user-data" 
    Set objUser = GetObject("LDAP://<SID="& normalizedSID & ">")
    FindUser=objUser.EmailAddress
End Function

希望这对其他人有用。

答案4

所有 Powershell 答案都已过时/不完整。本机 AD Powershell 命令将是:

Get-ADUser -Identity S-1-5-21-3968247570-3627839482-368725868-1110

你当然可以概括/扩展这一点。

Get-ADUser -Identity (Get-Clipboard)

或者

$SIDList = Get-Content -Path c:\path\to\listofsids.txt
$SIDList | % { Get-ADUser -Identity $_}

相关内容