当我有某个用户的 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 $_}