Entendiendo la System.DirectoryServices.ResultPropertyCollection
en PowerShell
Al trabajar con PowerShell y consultar Active Directory, es posible que te encuentres con un comportamiento desconcertante al intentar acceder a propiedades de la System.DirectoryServices.ResultPropertyCollection
. En esta publicación, desentrañaremos un problema común que se encuentra al obtener información a través de un DirectorySearcher
, específicamente, por qué dos salidas diferentes producen resultados inesperados. Vamos a explorar el problema, su raíz y cómo puedes resolverlo de manera efectiva.
El Problema
Has configurado un script de PowerShell que utiliza la clase DirectorySearcher
para encontrar objetos de computadora en Active Directory, pero te enfrentas a discrepancias en tu salida. Aquí hay una replicación simplificada de tu código:
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher.Filter = ("(objectclass=computer)")
$computers = $objSearcher.findall()
Cuando intentas imprimir los nombres de las computadoras, observas las siguientes dos salidas:
$computers | %{
"Nombre del servidor entre comillas $_.properties.name"
"Nombre del servidor no entre comillas " + $_.properties.name
}
Y luego:
$computers[0] | %{"$_.properties.name"; $_.properties.name}
El resultado muestra un nombre de tipo para la propiedad cuando está incluido entre comillas (System.DirectoryServices.SearchResult.properties.name
) pero un valor cuando no lo está. Entender esta matiz es clave para dominar la recuperación de propiedades en PowerShell.
¿Por Qué Difieren las Salidas?
La discrepancia surge de cómo PowerShell evalúa variables y propiedades en cadenas. Cuando incluyes $_
en una cadena, PowerShell lo analiza como un objeto completo:
-
Contexto de Comillas: Al usar
";"
en la cadena, como en"Nombre del servidor entre comillas $_.properties.name"
, PowerShell no evalúa la propiedad, sino que hace referencia al métodoToString
del objeto, que, en este caso, se default a el nombre de tipo de la propiedad. -
Contexto Sin Comillas: Por el contrario, cuando lo usas sin comillas, como en
"Nombre del servidor no entre comillas " + $_.properties.name
, PowerShell evalúa primero la propiedad y luego la concatena a la cadena. Así, recupera el valor real almacenado en la propiedad en lugar del nombre de tipo.
Corrigiendo la Salida
Para recuperar el valor de la propiedad deseado mientras estás dentro de una cadena entre comillas, puedes invocar explícitamente la evaluación utilizando la sintaxis de subexpresión:
"Nombre del servidor entre comillas $($_.properties.name)"
Este uso de $()
le dice a PowerShell que evalúe lo que hay dentro antes de continuar con el resto de la cadena, dando como resultado la salida correcta que esperabas.
Explorando la Colección de Propiedades del Resultado
Recuerda, al trabajar con ResultPropertyCollection
, estás tratando con una colección de propiedades. Siempre puedes explorar el modelo de objeto directamente desde la línea de comandos de PowerShell. Por ejemplo, canalizando $computers[0].properties
a Get-Member
revela información sobre los miembros y propiedades disponibles:
$computers[0].properties | Get-Member
Puedes ver la propiedad Values
, que recupera un ICollection
de los valores de la propiedad. Esta exploración mejora tu comprensión y te permite navegar a través de las propiedades de manera más efectiva.
Conclusión
Al trabajar con PowerShell y System.DirectoryServices
de Active Directory, es crucial entender cómo la evaluación de cadenas actúa sobre objetos y sus propiedades. Al reconocer los diferentes contextos en los que se accede a estas propiedades, puedes evitar confusiones y recuperar la información que necesitas en el formato que esperas.
Navegar por construcciones complejas de PowerShell como ResultPropertyCollection
puede parecer desalentador al principio, pero con práctica y una comprensión más profunda, descubrirás que se convierte en una segunda naturaleza en tu viaje de scripting.