Recuperar detalhes do usuário do Active Directory usando o SID

7

Como posso encontrar um usuário no meu AD quando tenho seu SID. Eu não quero depender de outros atributos, já que estou tentando detectar mudanças neles. Exemplo: Recebo uma mensagem sobre uma alteração no registro do usuário que contém:

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: -

Eu quero notificar o usuário sobre a alteração. Então, eu preciso da informação de sua conta do AD.

    
por er4z0r 09.03.2010 / 14:42

4 respostas

19

Inicie o Windows PowerShell e execute:

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

A saída deve ser algo como isto,

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

A "maneira LDAP" para fazer isso seria recuperar o objeto base com o GUID (ou SID), que recuperará apenas o objeto base e não terá dados de classe adicionais anexados. No entanto, a partir desse objeto base, você pode recuperar o real "distinguishedName" para o objeto do usuário. A recuperação do objeto de usuário usando o atributo "distinguishedName" retornará um objeto DirectoryEntry (.Net / C # / PowerShell) ou um objeto iadsUser (VBScript) com dados de classe completa e permitirá que você obtenha quaisquer outros dados de atributos necessários.

O problema é recuperar o objeto inicial com o GUID (ou SID). Algumas fontes dirão que você deve converter o GUID de formato de seqüência de caracteres (ou seja, {28c67c50-9778-47a4-a77a-bf56f238a0c4}) em uma representação de seqüência de caracteres da matriz de bytes (por exemplo, "\ 50 \ 7c \ c6 \ 28 \ 78 \ 97 \ a4 \ 47 \ 7a \ a7 \ bf \ 56 \ f2 \ 38 \ a0 \ c4 ") para passar para o LDAP. De acordo com a documentação da Microsoft , este não é o caso. Uma representação de string simples do GUID / SID é suficiente.

Veja uma amostra de como você pode ligar-se ao objeto por meio do GUID e, em seguida, recuperar o objeto de usuário real com dados de classe completos. Powershell realmente puxa o objeto completo se você ligar com o GUID. Se você usar o VBScript, precisará executar o processo de duas etapas.

Além disso, observe que, embora os documentos da Microsoft digam que vários formatos de string GUID são aceitáveis, o único que eu consegui usar com êxito é remover os caracteres {}. TAMBÉM , por favor note que isto NÃO é uma string "byte-array" correta, mas simplesmente a string GUID sem caracteres especiais.

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

O mesmo processo pode ser usado para uma ligação SID. A página do MSDN que descreve isso diz que há vários formatos de fstring disponíveis, mas o mais comum será o formato s-1-5 -...-...-...-....

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

* QUERYING *

Se você vai realizar uma consulta LDAP para encontrar o objeto (por exemplo, comparando 'objectGUID' a um byte-array ou 'objectSID' a um byte-array), é aí que você precisará fazer o "correto "conversão de matriz de bytes. É importante observar que o byte-matriz tem uma ordem diferente que a representação de seqüência de caracteres, pois é armazenada como BYW WORD WORD WORD-BYTES para GUID e leva em consideração a ordem endian. A conversão da matriz de bytes para um SID tem condições semelhantes.

Existem várias maneiras diferentes de realizar a conversão, a Technet possui um um simples algoritmo vbScript . Você também pode fazer algo mais extravagante com C # / VB.Net usando o System.Guid, ou através de um script simples no PowerShell (tem que amar o 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 $_) }

Você deve então poder consultar o objeto usando um filtro LDAP padrão:

(&(objectClass=User)(objectGUID=c\c6\a4\a7a\bf\f2\a0\c4))

... ou qualquer outra coisa que você esteja procurando. Isso deve funcionar para um SID também.

    
por 08.03.2010 / 21:36
2

OK. Eu encontrei uma maneira de fazer isso através do Active Directory. Para compeleza aqui está o código:

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

Espero que isso seja útil para os outros.

    
por 09.03.2010 / 14:41
1

Use PS:

$SID = "S-X-X-XX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXX"
Get-ADObject -IncludeDeletedObjects -Filter * -Properties * | where{$_.objectSid -eq $SID}
    
por 22.01.2016 / 11:08