El Blog de Gualtrysoft

Windows 2000/2003/2008, Active Directory, VBScript, Hyper-V, PowerShell y todo aquello interesante a la hora de usar, configurar y administrar Windows Server. También tenemos longanizas…

PowerShell: Cmdlet para Obtener la Cadena SID de un Array SID

Posted by urpiano en Domingo 21 \21\UTC octubre \21\UTC 2012

Cuando consultamos en un objeto DirectoryEntry su propiedad objectSID vemos que se trata de un array de Bytes, no de la típica cadena SID más amigable para el ser humano. Este Cmdlet permite obtener esta cadena SID, lo cual nos hace que, por ejemplo, podamos usar el SID para poder identificar estructuras SID conocidas. Esto resulta muy util cuando se consulta el atributo operacional tokenGroups, que contiene los SIDs de todos los grupos a los que pertenece un usuario, ya sea por membresía directa, heredada o por ser su grupo primario (atributo primaryGroupID).

El Cmdlet recibe el SID como parámetro. Éste puede ser de dos tipos:

La devolución del Cmdlet es un objeto System.String que contiene la cadena SID.

El Cmdlet incluye ayuda, pego a continuación la ayuda con modificador -Detailed (esta ayuda se basa en la prestación de ayuda basada en comentarios de PowerShell 2.0 ¿Qué todavía tienes la versión 1.0 y no la 2.0? ¿A qué esperas para instalarla si es mucho mejor?):

NOMBRE
    Get-StringSID
    
SINOPSIS
    Esta función recibe un SID y lo devuelve como cadena de SID.
    
SINTAXIS
    Get-StringSID [[-SID] ] []
    
DESCRIPCIÓN
    Esta función recibe un SID y lo devuelve como cadena de SID. Puede
    recibir tanto el propio SID (que es un array de bytes) como la propiedad
    objectSID de un objeto DirectoryEntry.
    

PARÁMETROS
    -SID 
        SID a obtener su cadena SID. Puede ser tanto un array de Bytes como un
        objeto PropertyValueCollection correspondiente a la propiedad objectSID
        de un objeto DirectoryEntry; en este caso, la función obtendrá el array
        de bytes que compone el SID para obtener su cadena SID.
        
    
        Este cmdlet admite los parámetros comunes Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer y OutVariable. Para obtener más información, escriba:
        "get-help about_commonparameters".
    
    -------------------------- EJEMPLO 1 --------------------------
    
    PS C:\>Get-StringSID -SID $arrSID
    
    La función devolverá la cadena SID del array de bytes $arrSID
    
    -------------------------- EJEMPLO 2 --------------------------
    
    PS C:\>Get-StringSID -SID $Usuario.objectSID
    
    La función devolverá la cadena SID correspondiente a la propiedad
    objectSID del objeto DirectoryEntry $Usuario
    
NOTAS
    Para ver los ejemplos, escriba: "get-help Get-StringSID -examples".
    Para obtener más información, escriba: "get-help Get-StringSID -detailed".
    Para obtener información técnica, escriba: "get-help Get-StringSID -full".

Function Get-StringSID($SID)
{
    # Comprobamos si hemos recibido directamente la propiedad objectSID de un
    # objeto DirectoryEntry; en caso afirmativo cambiaremos el parámetro para
    # que sea el array de bytes con el SID en lugar de un objeto del tipo
    # PropertyValueCollection, tipo que tiene la propiedad objectSID de un
    # objeto DirectoryEntry
    If(($SID.GetType()).Name -eq "PropertyValueCollection")
    {
        # Cambiamos el parámetro a array de Bytes invocando la propiedad Value
        # del objeto PropertyValueCollection recibido
        $SID = $SID.Value
    }
    # Comprobamos que se ha recibido un array de Bytes
    ElseIf(($SID.GetType()).Name -ne "Byte[]")
    {
        # Mostramos un mensaje indicado que el tipo no es válido y salimos de la
        # función
        Write-Host "Tipo no valido`:$(($SID.GetType()).Name)"
        Return
    }
    # Comenzamos a montar la devolucióniniciando con "S-" y agregando el primer
    # Byte, que contiene la revisión de SID
    $Devolucion = "S-$($SID[0].ToString())-"
    
    # Ahora debemos montar la autoridad, que consiste de los siguientes 6 bytes.
    # Si el 5º ó 6º byte no son cero se montará en la cadena cada byte en
    # hexadecimal con dos dígitos (1,2,3,4,5,6: 010203040506)
    If($SID[5] -ne 0 -or $SID[6] -ne 0)
    {
        $Devolucion = "$Devolucion$("{0:x2}{1:x2}{2:x2}{3:x2}{4:x2}{5:x2}" -f $SID[1..6])"
    }
    # Si tanto el 5º como el 6º bytes son cero, se deberá sumar el valor de los
    # otros cuatro bytes, desplazando a la izquierda el segundo 8 bits, el
    # tercero 16 y el cuarto 24 (un 1 desplazado 8 bits se convierte en 256)
    Else
    {
        # Asignamos el primer byte al valor; se asigna tal cual, pues este no
        # tiene que tener desplazamiento a la izquierda.
        $Value = $SID[1]
        # En este bucle iremos sumando los restantes bytes (2º, 3º y 4º),
        # desplazando, como dijimos antes, el 2º 8 bits, el 3º 16 y el 4º 24.
        For($i = 1;$i -lt 4;$i++)
        {
            # Obtenemos el valor del Byte
            $Byte = $SID[($i + 1)]
            # Lo desplazamos lo que corresponda según sea el 2º. eñ 3º o el 4º
            (1..(8 * $i))|ForEach{$Byte = $Byte * 2}
            # Sumamos lo obtenido al valor
            $Value = $Value + [Int32]$Byte
        }
        # Agregamos el valor obtenido de autoridad
        $Devolucion = "$Devolucion$($Value.ToString())"
    }
    # A continuación vamos a concatenar las sub-autoridades que haya
    # Lo primero es averiguar cuántas subautoridades hay. Este dato está en el
    # 8º byte
    $NumSubAthorities = [Int32]$SID[7]
    
    # En este bucle iremos agregando cada una de las sub-autoridades. Cada
    # sub-autoridad consta de 4 bytes
    For($i = 0; $i -lt $NumSubAthorities;$i++)
    {
        # Obtenemos el índice en el array del primer byte de la sub-autoridad
        $Indice = 8 + ($i * 4)
        # Determinados SIDs especiales presentarán un número de subautoridades
        # que no tendrán los correspondientes bytes, de ahí el tener que salir
        # del bucle si el índice obtenido es superior al total de bytes del SID
        If($SID.Count -le $Indice){Break}
        # La subautoridad es un entero sin signo de 32 bits. Usamos el método
        # ToUInt32 del objeto BitConverter, al que se le pasa como primer
        # parámetro un array de Bytes y como segundo el índice del primer
        # elemento del entero resultante; la función devolverá un entero de 32
        # bits sin signo compuesto por el del índice pasado y los tres
        # siguientes
        [UInt32]$SubAuthority = [System.BitConverter]::ToUInt32($SID,$Indice)
        # Agregamos la sub-autoridad, previo guión parra separarla
        $Devolucion = "$Devolucion-$($SubAuthority.ToString())"
    }
    # Una vez montado el SID, la función termina devolviéndola
    Return [String] $Devolucion

<#
    .SYNOPSIS
        Esta función recibe un SID y lo devuelve como cadena de SID.

    .DESCRIPTION
        Esta función recibe un SID y lo devuelve como cadena de SID. Puede
        recibir tanto el propio SID (que es un array de bytes) como la propiedad
        objectSID de un objeto DirectoryEntry.

    .PARAMETER  SID
        SID a obtener su cadena SID. Puede ser tanto un array de Bytes como un
        objeto PropertyValueCollection correspondiente a la propiedad objectSID
        de un objeto DirectoryEntry; en este caso, la función obtendrá el array
        de bytes que compone el SID para obtener su cadena SID.

    .EXAMPLE
        PS C:\> Get-StringSID -SID $arrSID
        La función devolverá la cadena SID del array de bytes $arrSID

    .EXAMPLE
        PS C:\> Get-StringSID -SID $Usuario.objectSID
        La función devolverá la cadena SID correspondiente a la propiedad
        objectSID del objeto DirectoryEntry $Usuario

    .INPUTS
        System.Byte[],System.DirectoryServices.PropertyValueCollection

    .OUTPUTS
        System.String

    .NOTES
        Fernando Reyes López © 2012

    .LINK
        http://freyes.svetlian.com

    .LINK
        https://urpiano.wordpress.com

#>

}

CODIGO

Una respuesta to “PowerShell: Cmdlet para Obtener la Cadena SID de un Array SID”

  1. […] PowerShell: Cmdlet para Obtener la Cadena SID de un Array SID […]

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: