Как мне найти пользователя в моем AD, если у меня есть его SID. Я не хочу полагаться на другие атрибуты, так как я пытаюсь обнаружить изменения в них. Пример: я получаю сообщение об изменении записи пользователя, содержащее:
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.
Запустите 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>
«Способ LDAP» для этого - получить базовый объект с GUID (или SID), который будет извлекать только базовый объект и не будет иметь дополнительных данных класса. Однако из этого базового объекта вы можете получить фактическое «отличительное имя» для пользовательского объекта. Получение объекта пользователя с использованием атрибута «visibleName» вернет объект 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, а затем получить фактический объект пользователя с полными данными класса. Powershell фактически извлекает весь объект, если вы выполняете привязку с помощью GUID. Если вы используете 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=$uSid>"
$user = [ADSI]$user.distinguishedName
* ЗАПРОС *
Если вы собираетесь выполнить запрос LDAP для поиска объекта (например, сравнивая objectGUID с байтовым массивом или objectSID с байтовым массивом), то именно тогда вам нужно будет выполнить «правильный» байтовый преобразование массива. Важно отметить, что байтовый массив имеет другой порядок, чем строковое представление, поскольку он хранится как DWORD-WORD-WORD-WORD-BYTES для GUID и ДЕЙСТВИТЕЛЬНО учитывает порядок байтов. Преобразование байтового массива для SID имеет аналогичные условия.
Есть несколько различных способов выполнить преобразование, Technet имеет простой алгоритм vbScript. Вы также можете сделать что-нибудь более интересное с C # / VB.Net с помощью System.Guid или с помощью простого скрипта в 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.
ХОРОШО. Я нашел способ сделать это через 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
Надеюсь, это будет полезно другим.
Используйте PS:
$SID = "S-X-X-XX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXX"
Get-ADObject -IncludeDeletedObjects -Filter * -Properties * | where{$_.objectSid -eq $SID}